Edit report at https://bugs.php.net/bug.php?id=65352&edit=1
ID: 65352 Comment by: seyferseed at mail dot ru Reported by: seyferseed at mail dot ru Summary: Method Closure::bind() can access private property of object Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.4.17 Block user comment: N Private report: N New Comment: You tell me about scope, i'm understand what you mean. But in my example i can change private property not in scrope. This is not about reading property, this is about setting private without setter. See examples. $bar not copy, bar link to private. $foo = new Foo(); $bar = & $reader($foo, 'bar'); $bar = 'tab'; This is not in class scope, this is just reference (link) to private property, but i can change it. I think this is wrong! And in this case too: $bar = & $foo->getBar(); $bar = "tab"; I think changing private property by reference in any case, with bind() or not, wrong. This is violation of encapsulation. Previous Comments: ------------------------------------------------------------------------ [2013-07-31 04:54:43] mail+php at requinix dot net Variable scope. With bind() you were creating a closure that executes in the scope of that class. That's what the third argument was about. It means the function can do anything that a normal member function could have done, like call private methods and access private variables. As with reflection, with great power comes great responsibility. If you want to get the error then omit the third argument so the function remains in the scope you were executing in (ie, the global scope). ------------------------------------------------------------------------ [2013-07-31 04:39:12] seyferseed at mail dot ru For PHP, yes, solved. But not for logic. I believe that to change the link to private property is very wrong. Should generate an error. ------------------------------------------------------------------------ [2013-07-31 04:30:13] mail+php at requinix dot net >$bar = $foo->getBar(); Simply making the function return by reference is not enough: you have to assign by reference too. Otherwise the function returns a reference, yes, but your assignment makes a copy. You need both of the &s. http://php.net/language.references.return The first note on the page says exactly that. Your version with Closure::bind() had both. That's why it worked. Resolved? ------------------------------------------------------------------------ [2013-07-31 02:19:17] seyferseed at mail dot ru If i'm add & there $bar = & $foo->getBar(); $bar = "tab"; echo $foo->getBar(); I really can change Private $foo to "tab". I'm so confused... I'm expected Fatal error: Cannot access private property But by reference there is no error. Maybe this is PHP "feature" and there is no bug. ------------------------------------------------------------------------ [2013-07-31 02:14:11] seyferseed at mail dot ru But if i'm add this function to class Foo by code it in class, i can't access private property! And this is right. You say, that my Getter function used in Closure::bind() can change (like Setter) private property and this is right? I don't think so. Example: class Foo { private $bar = 'baz'; public function &getBar() { return $this->bar; } } $foo = new Foo(); $bar = $foo->getBar(); $bar = "tab"; echo $foo->getBar(); It's still "bar". And i don't know how i can change Private property of class by reference in this case. It will be wrong, if i can. And now i'm take my getter public function &getBar() { return $this->bar; } Put it in Closure::bind() and i can change Private property. This is really wrong. If i can change it only in function, that binded to Closure::bind(), like $value = & Closure::bind(function & () use ($property) { $this->property = "tab"; return $this->$property; }, $object, $object)->__invoke(); It's okay, becouse it statically inside Foo. But Client code can change Private property by reference! Is that right? ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=65352 -- Edit this bug report at https://bugs.php.net/bug.php?id=65352&edit=1