2012-07-09 97 views
0

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

这是预期的行为。在PHP中,声明为静态的属性在创建的对象的所有实例中共享。也就是说,在dbPreparedObject或其继承的类的所有实例中只有一个$insert的实例。

您看到autoinsert_nRecord的原因都是var_dump s是因为那是您创建的最后一个对象。

考虑这个微小的变化:

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

+0

我想我的问题是如何定义应该由类继承的属性,而无需在类声明中明确定义它们? – grobolom 2012-07-09 16:28:15

+0

如果某个属性是公共的或受保护的,它将由任何子类继承,而不在子类中定义它们。 – drew010 2012-07-09 18:08:23

+0

对我来说,看起来很奇怪,如果我在一个子类中正确地继承了一个继承,那么它会影响其他子类中的继承。为什么继承或不继承的子类的属性会影响父类? – grobolom 2012-07-09 18:39:21

相关问题