什么时候自动加载器被调用?

F21*_*F21 8 php autoloader

我有一个使用spl_autoload_register()以下注册的自动加载器:

class MyAutoLoader{
   public function __construct(){
       spl_autoload_register(array($this, 'loader'));
   }

   public function loader($className){
       var_dump($className);
   }
}

$al = new MyAutoLoader(); //Register the autoloader
Run Code Online (Sandbox Code Playgroud)

var_dump(),自动加载器似乎被调用很多东西,数据要插入到数据库中,参数化的SQL查询以及不是:

string 'name' (length=4)

string 'a:2:{s:5:"label";s:4:"Name";s:8:"required";b:1;}' (length=48)

string 'en_US' (length=5)

string 'object' (length=6)

string 'name = ?' (length=8)
Run Code Online (Sandbox Code Playgroud)

这些东西永远不会是类,所以永远不应该使用newclass_exists()等等.

在什么情况下/函数调用是自动加载器调用?我想停止自动加载不是被调用类的"classNames",因为每个$className都被使用检查file_exist(),并且检查这些数据字符串是非常低效的.


问题解决了.我首先按照Brad的建议进行了回溯,并将跟踪转储到文件中(只需添加一个打开文件并附加到其上的小片段).

显然,痕迹非常大,但我选择了我能找到的最简单的一条.顺便说一下,这个跟踪碰巧是一个调用我编写的数据库(ORM)包装器来包装真棒RedBean ORM库的.我转储的结果$className也验证了,因为这些字符串是数据进出数据库.

话虽如此,我有一个__call()拦截我的数据库包装器的方法,做一些处理,将它传递给RedBean,处理结果,然后将其发送回调用者.

问题:在处理过程中,我正在调用is_subclass_of()instanceof,这显然会要求自动加载器尝试加载类(因为我们没有任何名为name =?loaded的类,也不存在).

解决方案是实际确保我们有一个object之前的呼叫is_subclass_of()instanceof:if(is_object($someproperty) && is_subclass_of($someproperty)).

如果$someproperty不是对象,则if立即短路instanceof并且is_subclass_of()永远不会被调用,这意味着永远不会调用自动加载器.

正如brad所提到的,将自动加载器中包含的各种东西都包含在内require_once可能会带来巨大的安全风险,同时,多次使用文件系统file_exists()也是非常低效的.

所以,综上所述,自动加载磁带机被称为每次使用时instanceof,is_subclass_of其他类类型的功能,阶级存在的功能和反射法,查尔斯在他的回答示意.

因此,故事的寓意是,如果您计划在混合类型的变量上使用类类型函数或上述任何函数,请在将其传递给类类型函数之前先检查它.

Cha*_*les 3

\n

在什么情况/函数调用下调用自动加载器?

\n
\n

我意识到这基本上已经成为次要的问题,但仍然值得回答。

\n

通过spl_autoload_register(PHP 5.1+) 或 PHP 8.0.0 之前注册的自动加载函数(已弃用 PHP 7.2.0)__autoload()函数之前注册的自动加载函数,在 \xe2\x80\x94 时调用,并且仅当 \xe2\x80\x94 PHP 需要访问以下类时调用尚未定义。

\n

除了少数例外,这种做法随处可见,例如class_exists,它有一个参数告诉 PHP 不要调用任何自动加载器,默认情况下为 true 会触发自动加载器,并且可以设置为 false 来不调用(class_exists() 的第二个参数)。

\n

PHP 手册有一个专门用于自动加载的页面。如果有任何困惑,我建议您查看一下。

\n