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

问题描述 投票:0回答:2

我有一个使用

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

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)

这些东西永远不会是类,所以永远不应该使用

new
class_exists()
等加载。

在什么情况下/函数调用被称为自动加载器?我想停止自动加载不是被调用的类的“classNames”,因为每个

$className
都使用
file_exist()
进行检查,并具有这些数据字符串检查效率很低。


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

显然,痕迹很大,但我选择了我能找到的最简单的一个。顺便说一句,该跟踪恰好是我编写的一个称为数据库 (ORM) 包装器的跟踪,用于包装令人敬畏的 RedBean ORM 库。我转储的结果

$className
也验证了这一点,因为这些字符串是数据正在进入或从数据库中出来。

话虽如此,我有一个

__call()
可以拦截数据库包装器的方法,进行一些处理,将其传递给 RedBean,处理结果,然后将其发送回调用者。

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

name =?
的类,也不存在)。

解决方案是在调用

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
、其他类类型函数、类存在函数和反射方法时都会调用自动加载器,正如 Charles 在他的回答中指出的那样。

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

php autoloader
2个回答
3
投票

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

我意识到,鉴于评论中指出的问题,这基本上已经成为一个“次要”问题,但它仍然值得回答。 通过

spl_autoload_register

(PHP 5.1+)或 PHP 8.0.0 之前(已弃用 PHP 7.2.0)注册的自动加载函数 
__autoload()
 函数,在且仅在 PHP 需要访问类时调用尚未定义。
这是在

到处

完成的,除了少数例外,例如class_exists

,它有一个参数告诉 PHP 不要调用任何自动加载器,默认情况下为 true 会触发自动加载器,并且可以设置为 false 来不调用(第二个) class_exists() 的参数。
PHP 手册有

一个专门用于自动加载的页面

。如果有任何困惑,我建议您查看一下。


0
投票
debug_backtrace

debug_print_backtrace
来找出自动加载函数到底在哪里被调用。

从技术上讲,只有当脚本引用不存在的类名时,PHP 才应调用它。

© www.soinside.com 2019 - 2024. All rights reserved.