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?
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.
The part of the code that is shown below will look crazy, but it is written exclusively for educational purposes.
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.
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>"); ?> 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.
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.
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
__set - MaximProSource: https://ru.stackoverflow.com/questions/528954/
All Articles
private function __set() {}. php.net/manual/en/language.oop5.visibility.php - E_pprivate function __set() {}- fairy tales - MaximPro