php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65006 spl_autoload_register fails with multiple callables using self, same method
Submitted: 2013-06-10 15:05 UTC Modified: 2016-06-20 14:32 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: byoung2 at gmail dot com Assigned:
Status: Verified Package: SPL related
PHP Version: 5.4.16 OS: Windows or Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: byoung2 at gmail dot com
New email:
PHP Version: OS:

 

 [2013-06-10 15:05 UTC] 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
        )

)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-20 14:32 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2016-06-20 14:32 UTC] cmb@php.net
Confirmed: <https://3v4l.org/aMkoi>. Obviously, hhvm gets that
right.
 [2017-07-15 06:45 UTC] 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());
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC