一个类中的静态属性由另一个类设置

时间:2012-07-09 15:36:32

标签: php inheritance static prepared-statement

我一直在研究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 = ""

1 个答案:

答案 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需要是静态的,或者你有什么其他选择,所以你不会遇到这个问题。