|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-04-20 06:46 UTC] stas@php.net
Description:
------------
__clone and __destruct check access to protected methods differently from other
methods. They have
custom implementation and while other methods allow access to siblings in the
same tree to protected
functions, those do not. See implementation for regular ones:
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc),
EG(scope)))) {
if (zobj->ce->__call) {
fbc = zend_get_user_call_function(zobj->ce, method_name,
method_len);
} else {
zend_error_noreturn(E_ERROR, "Call to %s method %s::%s() from
context '%s'",
zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc),
method_name, EG(scope) ?
EG(scope)->name : "");
}
}
and for __clone:
if (UNEXPECTED(!zend_check_protected(clone->common.scope, EG(scope)))) {
zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from
context '%s'", ce->name,
EG(scope) ? EG(scope)->name : "");
}
it can be seen that __clone does not use zend_get_function_root_class(). Same
happens for destructor.
I see no reason for that and I think they should be brought in sync with the
rest of the code. See also:
http://www.mail-archive.com/internals@lists.php.net/msg57424.html
Test script:
---------------
abstract class BaseClass {
abstract protected function __clone();
}
class MommasBoy extends BaseClass {
protected function __clone() {
echo __METHOD__, "\n";
}
}
class LatchkeyKid extends BaseClass {
public function __construct() {
echo 'In ', __CLASS__, ":\n";
$kid = new MommasBoy();
$kid = clone $kid;
}
public function __clone() {}
}
$obj = new LatchkeyKid();
Expected result:
----------------
In LatchkeyKid:
MommasBoy::__clone
Actual result:
--------------
Fatal error: Call to protected MommasBoy::__clone() from context 'LatchkeyKid' in
bug.php on line 16
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 03:00:02 2025 UTC |
reproducable in PHP 5.5.2 class Foo { public function getClone() { return clone $this; } private function __clone() {} } class Bar extends Foo {} (new Bar)->getClone(); // Call to private Bar::__clone() from context 'Foo'