【问题标题】:What's the principle of autoloading in PHP?PHP中自动加载的原理是什么?
【发布时间】:2010-02-20 16:59:20
【问题描述】:

spl_autoload_register可以做这种工作,但我不明白这种工作是怎么做的?

spl_autoload_register(array('Doctrine', 'autoload'));

【问题讨论】:

    标签: php spl-autoload-register


    【解决方案1】:

    基本思想是您不必再编写include/require 指令:每当您尝试使用未定义的类时,PHP 都会调用自动加载器。

    那么,自动加载器的工作就是确定应该加载哪个文件,然后include 它,所以类被定义了。

    然后 PHP 可以使用该类,就好像您是编写 include 指令的人一样,该指令实际上已在自动加载函数中执行。


    “诀窍”是自动加载功能:

    • 只接收类名
    • 必须确定要加载哪个文件 - 即哪个文件包含该类。

    这就是命名约定的原因,例如 PEAR 约定,它表示 Project_SubProject_Component_Name 之类的类映射到 Project/SubProject/Component/Name.php 之类的文件——即类名中的“_”被替换为文件系统上的斜线(目录、子目录)


    例如,如果您查看Doctrine_Core::autoload 方法,在您的案例中该方法将被称为自动加载器,它包含这部分代码(在处理某些特定情况后) :

    $class = self::getPath() 
                . DIRECTORY_SEPARATOR . 
                str_replace('_', DIRECTORY_SEPARATOR, $className) 
                . '.php';
    if (file_exists($class)) {
        require $class;
        return true;
    }
    return false;
    

    这意味着类名映射到文件系统,将“_”替换为“/”,并在文件名中添加最后一个.php

    例如,如果您尝试使用 Doctrine_Query_Filter_Chain 类,而 PHP 不知道它,则将调用 Doctrine_Core::autoload 函数;它将确定应该加载的文件是 Doctrine/Query/Filter/Chain.php ;并且由于该文件存在,它将被包含在内——这意味着 PHP 现在“知道”Doctrine_Query_Filter_Chain 类。

    【讨论】:

    • 如果注册了很多类,是全部执行还是只执行匹配Doctrine的一个?
    • 如果你有几个用spl_autoload_register注册的自动加载函数,你会有一个自动加载函数的“队列”。 PHP 将(引用php.net/spl_autoload_register)“按照定义的顺序遍历它们中的每一个”;;;这意味着将调用第一个函数;如果该类仍然不存在,则将调用第二个类;等等——类名的独立性。
    • 在我之前的评论中添加一点信息:您使用的"Doctrine" 字符串仅意味着您正在注册的自动加载功能是autoload 类中的静态方法autoload Doctrine (请参阅此处的“回调”:php.net/manual/en/language.pseudo-types.php ;;;它没有说明自动加载器能够自动加载哪些类。
    • 我点击了那个链接,似乎spl_autoload_register 不接受数组作为参数,但是为什么上面仍然有效?
    • spl_autoload_register 接受 "callback" 作为其第一个参数;一个包含类名作为第一个元素,静态方法名作为第二个元素的数组是一个有效的回调——请参阅我在第二条评论中发布的链接。
    猜你喜欢
    • 2011-04-06
    • 1970-01-01
    • 2019-02-15
    • 2019-06-17
    • 1970-01-01
    • 2012-10-22
    • 2019-10-01
    • 2011-04-14
    • 2021-09-04
    相关资源
    最近更新 更多