记一次spl_autoload_register踩坑

定义: spl_autoload_register – 注册给定的函数作为 __autoload 的实现 【官方文档】

简单说就是当我们使用未引用的类时会触发这个函数执行,例如:

示例1

根据这个特性,我们可以实现自动的类加载功能,例如:

示例2

一切看起来都是如此美好,但是问题来了,在测试中我发现如下问题:

坑

虽然成功加载了目标类,但是spl_autoload_register被触发了两次,外部实例化类的地方只有一处,显然这是不正常的(红框内的类按照处理逻辑是不应该被加载的)。

经查发现出问题的函数是 class_exists

class_exists

它的第二个参数 autoload 默认是 true, 这就导致如果指定的类 $class_name 不存在就会触发__autoload, 而spl_autoload_register是__autoload的实现,所以spl_autoload_register就被触发了。

解决方法也简单,就是在指定参数autoload为false即可:

示例3

注意此处的Demo是放在test目录下面的,和上面示例12Demo放同级目录不同

类似的常用方法还有: class_alias, trait_exists,interface_exists 等。

细心的大佬可能会发现在官方文档里面已经有人提出这个问题了:

明人不说暗话,这个坑出现在我项目 QQ空间自动导出 里,项目不大所以没有使用三方框架,自己写了一个简单的类自动加载,替代繁琐的require过程。 项目测试运行正常,但是调试的时候发现,接口调用的同时自动模型构建代码被触发执行了,原因是class_exists触发了自动加载,导致substr截取的所有字符串都当做了类来处理,结果碰巧有一个字符串就是我的自动代码构建类,这就很有意思了。

来个简单安全Case:

payload

nice~

关注作者公众号,获取更多资源!
赏作者一杯咖啡~