Bug #65006 [Ver->Csd]: spl_autoload_register fails with multiple callables using self, same method

From: Date: Wed, 10 Jun 2020 09:30:48 +0000
Subject: Bug #65006 [Ver->Csd]: spl_autoload_register fails with multiple callables using self, same method
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-227394@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=65006&edit=1 ID: 65006 Updated by: nikic@php.net Reported by: byoung2 at gmail dot com Summary: spl_autoload_register fails with multiple callables using self, same method -Status: Verified +Status: Closed Type: Bug Package: SPL related Operating System: Windows or Linux PHP Version: 5.4.16 Block user comment: N Private report: N New Comment: Automatic comment on behalf of nikita.ppv@gmail.com Revision: http://git.php.net/?p=php-src.git;a=commit;h=94df2f697fa1434bfca0d729a14abd53f3e2586e Log: Fix bug #65006 Previous Comments: ------------------------------------------------------------------------ [2017-07-15 06:45:17] danielklein at airpost dot net Try the following code with SHOW_BUG = true, then rerun it with SHOW_BUG = false. I've reproduced this bug in PHP 5.4, 5.5, 5.6 and 7.0. I think the bug is because PHP is storing the key 'self' or 'static' against the function, instead of resolving it to the class name at the time the function is registered. This implies that it is resolved every time the function is called, instead of only once, when the function is registered. <?php const SHOW_BUG = true; class Autoloader { const AUTOLOAD_METHOD = 'autoload'; public static function register() { if (SHOW_BUG) { spl_autoload_register(['static', static::AUTOLOAD_METHOD]); } else { spl_autoload_register([get_called_class(), static::AUTOLOAD_METHOD]); } } protected static function autoload($class_name) { $words = self::split_class_name_into_words($class_name); } } class Autoloader2 extends Autoloader { } class Autoloader3 extends Autoloader { } Autoloader2::register(); Autoloader::register(); Autoloader3::register(); var_dump(spl_autoload_functions()); ------------------------------------------------------------------------ [2016-06-20 14:32:49] cmb@php.net Confirmed: <https://3v4l.org/aMkoi>. Obviously, hhvm gets that right. ------------------------------------------------------------------------ [2013-06-10 15:05:14] byoung2 at gmail dot com Description: ------------ spl_autoload_register should properly resolve 'self' to the current execution scope, which it does for the 'first' class, but it does not for the 'second' class. Only the first autoload is registered. If I change the method name in the 'second' class to 'load2' for example, and register array('self','load2') using spl_autoload_register, it works. It also works if I replace 'self' with __CLASS__, which I have done as a workaround. Using 'static' instead of 'self' has the same bug, but __CLASS__ won't work in this case if you want late static binding. Test script: --------------- <?php first::init(); second::init(); print_r(spl_autoload_functions()); class first { public static function init() { spl_autoload_register(array('self','load')); } public static function load($class) {} } class second { public static function init() { spl_autoload_register(array('self','load')); } public static function load($class){} } Expected result: ---------------- Array ( [0] => Array ( [0] => first [1] => load ) [1] => Array ( [0] => second [1] => load ) ) Actual result: -------------- Array ( [0] => Array ( [0] => first [1] => load ) ) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=65006&edit=1

« previous php.bugs (#227394) next »