今天在做组件化的 Model 设计,打算采用单例模式

打算使用父类 Model 统一定义单例模式的 instance() 方法,结果发现产生了这样的现象:

echo get_class(UserModel()->instance());

输出结果是:

Model

这就导致很神奇的事情发生了,当我拿 UserModel()->instance()->data  的时候会拿到 Model 预定义的 Model,在子类覆盖父类的 data 丝毫不起作用。

查了一下原因,结果就出现在 new self 上。

self 指的是被执行的代码段所在的类,这个情况里,就是 instance() 方法定义在 Model 这个父类,所以 self 就是指的 Model 这个父类。 static 指的是真正执行代码段的类,在 UserModel::instance() 则个情况中, static 就是指 UserModel 这个类。

所以现在只需要将 new self 改为 new static 就可以小小的解决这个问题。 但是还有一些问题没有处理好!

我们用的是 self::$instance 这个静态成员变量来进行是否已经实例化判断。

刚才说过, self 指代的是被执行代码段被定义的类,所以如果仅仅修改 new self 还不足够,因为只要 Model 或者 Model 的子类被实例化过一次之后,Model::$instance 就已经有了值,再使用任意一个 Model 的子类的 instance() 方法,将返回第一次被实例化的对象,这就超出了我们的预期。

所以至少要修改成这样才不会出现上边说的那个 Bug:


有时候不够了解语言的语法,的确会给自己挖坑跳呢…