鍍金池/ 問答/PHP/ spl_autoload_register自動(dòng)加載函數(shù)的參數(shù)問題。

spl_autoload_register自動(dòng)加載函數(shù)的參數(shù)問題。

源碼如下:

class ComposerAutoloaderInit
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';//注意這一行。
        }
    }

    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        .
        .
        //省略很多代碼
        .
        .

在我調(diào)用 ComposerAutoloaderInit::getLoader() 方法的時(shí)候,發(fā)現(xiàn) loadClassLoader 中的 if 執(zhí)行了(有注釋的那行)。但是 if 有條件判斷 'ComposerAutoloadClassLoader' === $class ,而 spl_autoload_register 注冊的時(shí)候似乎沒有傳遞 $class 進(jìn)去。請 $class 是如何定義的?

回答
編輯回答
亮瞎她

11111111

2017年8月4日 21:22
編輯回答
故林

答:是 Zend 引擎層(即 PHP 底層)實(shí)現(xiàn)的回調(diào),和參數(shù)傳入。

解釋如下:

了解 spl_autoload_register

spl_autoload_register 做了什么

將函數(shù)注冊到SPL __autoload函數(shù)隊(duì)列中。如果該隊(duì)列中的函數(shù)尚未激活,則激活它們。

注意:此時(shí)并沒有調(diào)用你所注冊的自動(dòng)加載函數(shù) ComposerAutoloaderInit:: loadClassLoader

__autoload函數(shù)隊(duì)列是什么

__autoload函數(shù)隊(duì)列Zend 內(nèi)核維護(hù)的一個(gè)自動(dòng) hash 隊(duì)列。
Zend 中對應(yīng)的數(shù)據(jù)結(jié)構(gòu)定義如下:(注意結(jié)構(gòu)體成員:autoload_functions

ZEND_BEGIN_MODULE_GLOBALS(spl)
    char *       autoload_extensions;
    HashTable *  autoload_functions;
    int          autoload_running;
    int          autoload_extensions_len;
    intptr_t     hash_mask_handle;
    intptr_t     hash_mask_handlers;
    int          hash_mask_init;
ZEND_END_MODULE_GLOBALS(spl)

隊(duì)列中的函數(shù)原型:void auto_func_name(string $class_name)

什么時(shí)候調(diào)用回調(diào)函數(shù)

首先需要了解,執(zhí)行 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 時(shí),發(fā)生了什么:
PHP 中,new 一個(gè)對象時(shí),首先會(huì)在已經(jīng)引入的文件中搜索匹配對應(yīng)的命名空間/類名,如果搜索不到,會(huì)觸發(fā)自動(dòng)加載函數(shù),即一次調(diào)用 __autoload函數(shù)隊(duì)列 中所注冊的方法,調(diào)用時(shí)會(huì)將需要實(shí)例化的 完整命名空間 + 類名傳入。

2018年4月6日 15:13
編輯回答
執(zhí)念

首先要明確通過 spl_autoload_register 注冊的,不是類,也不是類所對應(yīng)的文件,而是自動(dòng)加載方法。
那么 spl_autoload_register 的參數(shù)就很明確,是需要一個(gè)自動(dòng)加載的方法的。
這個(gè)方法,就是代碼里的 array('ComposerAutoloaderInit', 'loadClassLoader') 。
而真正需要加載類的時(shí)候,PHP 會(huì)調(diào)用這個(gè)方法,即 ComposerAutoloaderInit::loadClassLoader ,帶上類名。

理解這個(gè)過程的關(guān)鍵,是分清楚注冊和調(diào)用是兩個(gè)流程,而這里,調(diào)用者并不是你的代碼,而是 PHP 本身,所以你自然就看不到如何傳入類名的了。

2018年5月25日 11:44