Edit report at https://bugs.php.net/bug.php?id=65352&edit=1
ID: 65352
Comment by: mail+php at requinix dot net
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:
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).
Previous Comments:
------------------------------------------------------------------------
[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?
------------------------------------------------------------------------
[2013-07-30 18:09:38] mail+php at requinix dot net
As noted in Closure::bind(),
"public static Closure Closure::bind ( Closure $closure , object $newthis [,
mixed
$newscope = 'static' ] )
newscope
The class scope to which associate the closure is to be associated, or 'static'
to
keep the current one. If an object is given, the type of the object will be
used
instead. This determines the visibility of protected and private methods of the
bound object."
You changed the scope of the function to be that of inside $foo. Naturally it
would have access to private members. If you don't want it to do that then omit
newscope=$object.
------------------------------------------------------------------------
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