从父类访问子类静态变量?

Hai*_*ood 12 php static reference static-members

我有一个基类,我需要在子类中引用的类上调用函数.

很容易,

class base_class {

    public function doSomethingWithReference(){
        $this->reference->doSomething();
    }
}

class extended_class extends base_class{

    protected $reference;

    public function __construct($ref){
        $this->reference = $ref;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这显然很好,

但是,当我调试时,我并不关心它的价值 $this->reference

但是,$this->reference引用的对象是巨大的!

所以,当我这样做时,print_r($instanceOfExtendedClass)我得到了该对象的打印件.

现在,对于每个扩展的类,引用都是不同的base_class.

我想要做的只是referenceextended_class类上设置为静态属性.

但是,然后更改doSomethingWithReferenceself::$reference抛出未定义的变量错误.

相反,设置静态变量base_class并从中修改它extended_class不起作用,因为它改变了从该类扩展的所有内容的变量.

有没有办法做到这一点,所以我不打印出来的$this->reference

Cha*_*les 18

因为您使用的是PHP 5.3,所以您可以使用后期静态绑定来解析在运行时对正确类的静态调用.

class base_class {

    public function doSomethingWithReference(){
        static::$reference->doSomething();
    }

}

class extended_class extends base_class{

    protected static $reference;

    public function __construct($ref){
        static::$reference = $ref;
    }

}
Run Code Online (Sandbox Code Playgroud)

大发提醒:这一个extended_class::$reference将要共享之间所有的的extended_class实例.如果这不是你想要的,这是行不通的.

您似乎真的担心内存或资源使用.在PHP中,所有对象都通过引用传递.这意味着将对象作为参数传递或创建它的副本等不会消耗额外的内存.如果需要在许多其他对象中引用对象,那么这样做不会消耗额外的内存.


如果我有extended_class和另一个相同的类(比如extended_class1),他们也会共享引用吗?或者所有extended_class'实例是否共享一个引用,而所有extended_class1'实例将共享另一个(理想情况)?

看起来共享基于静态变量的定义位置.两个示例,都来自PHP交互式提示:

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } }
php > class Base { protected static $ref; public function foo() { echo static::$ref->me, "\n"; } }
php > class Inherit_1 extends Base { public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_2 extends Base { public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_3 extends Inherit_1 {}
php > $shared_1 = new Shared(1)
php > ;
php > $shared_2 = new Shared(2);
php > $shared_3 = new Shared(3);
php >
php > $in_1 = new Inherit_1($shared_1);
php > $in_2 = new Inherit_2($shared_2);
php > $in_3 = new Inherit_3($shared_3);
php >
php > $in_1->foo();
3
php > $in_2->foo();
3
php > $in_3->foo();
3
Run Code Online (Sandbox Code Playgroud)

在这种情况下,因为引用存在于基类中,所以每个人都看到相同的引用.我认为这有点道理.

当我们为每个子类声明引用时会发生什么...大部分时间?

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } }
php > class Base { public function foo() { echo static::$ref->me, "\n"; } }
php > class Inherit_1 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_2 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_3 extends Inherit_1 {}
php > class Inherit_4 extends Inherit_1 { protected static $ref; }
php > $shared_1 = new Shared(1);
php > $shared_2 = new Shared(2);
php > $shared_3 = new Shared(3);
php > $shared_4 = new Shared(4);
php > $in_1 = new Inherit_1($shared_1);
php > $in_2 = new Inherit_2($shared_2);
php > $in_3 = new Inherit_3($shared_3);
php > $in_4 = new Inherit_4($shared_4);
php > $in_1->foo();
3
php > $in_2->foo();
2
php > $in_3->foo();
3
php > $in_4->foo();
4
Run Code Online (Sandbox Code Playgroud)

因为3继承自1而没有声明它自己的静态属性,所以它继承了1.当我们将3设置为Shared(3)时,它覆盖了1的现有Shared(1).

结论:要使其工作,需要在需要单个唯一引用的每个类中声明属性.请注意,此代码自5.4.x起有效.