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

Php 一个类中的静态属性由另一个类设置,php,inheritance,static,prepared-statement,Php,Inheritance,Static,Prepared Statement,我在PHP5.3.x中开发了一小部分遵循活动记录模式的类。但是,在处理静态属性时,我遇到了一个问题。以下是我一直在测试的代码: <?php class dbPreparedObject { public static $insert = ""; public function __construct() { static::$insert = "autoinsert_".get_called_class(); } } class gtReco

我在PHP5.3.x中开发了一小部分遵循活动记录模式的类。但是,在处理静态属性时,我遇到了一个问题。以下是我一直在测试的代码:

<?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);
一、 但是,希望第一个字符串读取
autoinsert\gtRecord


似乎没有被子类实例化的静态属性被绑定在一起。有没有办法在每个子类中不声明
public static$insert=”“
而将它们分开?

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

您看到两个
var\u dump
s的
autoinsert\u nRecord
的原因是,这是您创建的最后一个对象

考虑一下这个小变化:

$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_转储之后,值是
\gtRecord
,但是一旦创建了
nRecord
对象,静态属性(对于所有dbPreparedObject对象)就会更改为
nRecord
,因为这是最后一个类

因此,如果您计划拥有该类的多个实例,
$insert
不能是静态的,因为它并不总是包含给定代码所期望的值,因为静态
$insert
属性只有一个副本对所有对象都是相同的。一旦在一个对象中更改了它,就可以在所有对象中更改它


因此,我们需要问为什么
$insert
需要是静态的,或者您还有哪些其他选项可以避免遇到此问题。

我想我的问题是,如何定义应该由类继承的属性,而不在类声明中显式定义它们?如果属性是公共的或受保护的,它将被任何子类继承,而不在子类中定义它们。我觉得奇怪的是,如果我在子类中正确地更改了一个继承项,它将影响其他子类中的继承。为什么子类的属性,不管继承与否,都会影响父类?只有在它是静态的情况下才会影响父类,因为静态属性只有一个在类的所有实例(及其子类)之间共享的实例。是的,正常的非静态方式如下:
class Foo{public$bar;public$baz='value';}
如果不创建类的具体实例,就无法访问这样声明的属性,如果您在类中,可以使用
$obj->property
$this->property
引用它们。
$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)