一段时间之前遇到过一个坑,CI中控制器一个方法总是会被加载两次。控制器类名叫Index,而方法名叫index。这个index方法总是会被执行两次,接下来探究一番吧。

众所周知,PHP中类的构造函数是__construct()。类被实例化的时候会执行__construct方法,如果这个类中没有那么执行其父类的__construct方法;而如果子类中有__construct方法,则不会自动执行其父类的__construct方法,如果想调用父类的构造函数则需要使用parent关键字。下面看一段代码测试。

上面的代码会输出 IndexChild __construct 。如果注释掉子类的__construct方法,那么输出 Index __construct 。

除了__construct方法,在PHP4中还有另外一种构造函数,就是跟Java相同的语法:与类名同名的方法。手册里是这样写的。(这种写法在PHP7里面依然兼容。)在上面的例子中,显然就是这么写的。

这个会输出 Index function index 。

这样开头的问题似乎是解决了。但是现在思绪有点乱,它到底是怎么加载这几种构造函数的?那继续来探究。下面的这个例子是用来测试他们共同存在情况了。

运行上面程序,输出 IndexChild __construct ,也就是说PHP5增加的__construct构造函数优先级是比同名函数要高的。

注释掉IndexChild的__construct方法,输出 IndexChild function indexChild 。

恢复原来的注释,注释掉indexChild方法,输出 Index __construct 。

这样基本就清晰了。也就是说,PHP类的构造方法是一级一级查找的,首先在本类中寻找__construct方法,不存在则寻找类同名方法,再不存在寻找父类的__construct方法,再不存在则寻找父类同名方法,再不存在寻找父类的父类……另外一个需要注意的是,PHP的类、函数名都不区分大小写,所以就算小写的同名,还是会加载。