Let's say there is a class in it there is a getter and a setter

I want the setter to work only in the classroom (it worked only for actions in the classroom, but not everywhere)

How to do this?

  • Not quite clear question. But can private function __set() {} . php.net/manual/en/language.oop5.visibility.php - E_p
  • unfortunately private function __set() {} - fairy tales - MaximPro
  • Then write your setter. Magic methods are certainly cool, but it's better not to use it once again. - E_p
  • I hope by the setter you do not mean the magic method __set? ...... by the properties outside the class do you mean the properties of another object? - Lesiuk Alexey

3 answers 3

Preamble

Sometimes there is a desire to do something that the developers of the language have not foreseen. Often it occurs because of the wrong design, and often because of the need to track down a cunning bug.

Disclaimer aka disclaimer

The part of the code that is shown below will look crazy, but it is written exclusively for educational purposes.

We clarify the task

So, we formalize the task. And it will sound like "how to prevent one code / function from calling another code / function under certain conditions." And you also need to decide what is "ban." This may be a compilation error or an exception at run time. It may also be just ignoring the call or writing to the log. But these are implementation details and at the moment we are not interested.

solution via caller

In php and many other dynamic languages ​​it is possible to request a call stack. After reviewing it, you can understand the context of the call. Below is the code that allows you to set who can call it in a seter.

 <?php # часть кода скопировано с php.net class user { public function __construct() { # это вызов из класса $this->foo = bar; } # собственно сеттер, в котором все и происходит public function __set($key, $value) { $trace = debug_backtrace(); $caller_class = ""; if (count($trace) > 1) { # в $trace[0] находиться текущая функция # в $trace[1] находиться вызывающая функция $caller = $trace[1]; # возьмом имя класса, там есть ещё много полей, вплоть до номера строки if (isset($caller["class"])) { $caller_class = $caller["class"]; } } print ("call from \n"); if ($caller_class == "") { print("функция вызывается напрямую\n"); } else if ($caller_class === get_class()) { print ("функция взывается внутри класса\n"); } else { print("функция вызывается с класса $caller_class\n"); } } } # а это тестовый класс, который нужен исключительно для теста вызова # с другого класса. class test_user { public function test() { $u = new user; $u->foo = "bar"; } } print("<pre>"); $u = new user; $u->foo = "bar"; #----------------- $t = new test_user; $t->test(); print("</pre>"); ?> 

instead of conclusion

The debug_backtrace() function for retrieving the current framerays is quite "heavy". And to use it in production "Hayload code" is ugly and fraught with a drop in performance. But if something happened out of the blue and you need to secure a situation, then of course you can.

  • it turns out that there is no way out, you need to redesign the project as I understood it - MaximPro
  • Yes, and there are alternatives. For example, make a "private class" that will be used only by your class. And the outside world will not know about the inner class. Therefore, it is possible to distinguish very well the accessibility "from outside" and "inside". Google on pimpl. - KoVadim
  • > the setter itself, in which everything happens, is the wrong statement ....... the magic set method is not a setter in this example .... - Lesiuk Alexey
  • And what is it? Magically set? - KoVadim
  • from Wikipedia - Setter method, setter (English setter) or modifying method, mutator (English mutator) - a method used in object-oriented programming to assign a value to an encapsulated field, for example, by processing invalid assignments . - Lesiuk Alexey

You can go the other way. The magic __set method __set called only when you try to set properties of an object that are not public .

Do you want __set not to handle properties when called outside the class? Then the solution I propose is to delete the __set() method .

Inside the class, the properties will remain as before, and the ability to set properties from outside (not public properties) disappears.

  • Yes, that's exactly what I did) before your advice in a couple of hours - MaximPro

I want the setter to work only in the classroom, and the getter is everywhere

setter make private (will work only in the class) getter make public and you can call it outside the class. (you can also make it static if you need to call it without creating an object instance)

I hope you are not confused what the setter and the magic method __set.

How to prevent the __set magic method from handling properties outside the class

Prohibit - in any way, but you can not access properties outside this class and the magic method will not process them

  • Setter is only public! haven't you read the documentation? Yes, and I kind of wrote in the title what I meant - __set - MaximPro
  • where does the setter and __set? > setter is only public! - no, the setter is any method that updates the properties of an object and it can be public! Do not confuse concepts (things should be called with their names) - Lesiuk Alexey