我一直在研究PHP 5.3.x中一小部分遵循Active Record模式的类。但是,在使用静态属性时,我遇到了一个问题。以下是我用以下方法测试的代码:
<?php
class dbPreparedObject {
public static $insert = "";
public function __construct() {
static::$insert = "autoinsert_".get_called_class();
}
}
class gtRecord extends dbPreparedObject {}
class nRecord extends dbPreparedObject {}
$a = new gtRecord();
$b = new nRecord();
var_dump(gtRecord::$insert);
var_dump(nRecord::$insert);
输出:
string(18) "autoinsert_nRecord"
string(18) "autoinsert_nRecord"
但是,我希望第一个字符串读取autoinsert_gtRecord
。
似乎未将子类实例化的静态属性绑定在一起。有没有办法将它们分开而不在每个子类中声明public static $insert = ""
?
答案 0 :(得分:1)
这是预期的行为。在PHP中,声明为static的属性在创建的对象的所有实例之间共享。也就是说,$insert
或其继承类的所有实例中只有一个dbPreparedObject
实例。
您看到autoinsert_nRecord
两个var_dump
的原因是因为那是您创建的最后一个对象。
考虑这个小改动:
$a = new gtRecord();
var_dump(gtRecord::$insert); // autoinsert_gtRecord
$b = new nRecord();
var_dump(nRecord::$insert); // autoinsert_nRecord
var_dump(gtRecord::$insert); // autoinsert_nRecord (because it was the last one set)
在第一个var_dump之后,值为_gtRecord
,但是一旦创建了nRecord
对象,静态属性就会被更改(对于所有dbPreparedObject对象)为nRecord
,因为那是最后一堂课。
因此,如果您计划拥有此类的多个实例,$insert
不能是静态的,因为它不会始终包含您希望给定代码的值,因为只有一个静态$insert
的副本对所有对象都相同的属性。一旦在一个对象中更改它,就可以在所有对象中更改它。
所以我们需要问为什么$insert
需要是静态的,或者你有什么其他选择,所以你不会遇到这个问题。