简体   繁体   English

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

[英]Access child class static variables from parent class?

I have a base class that I need to call functions on a class that is referenced in the child class. 我有一个基类,我需要在子类中引用的类上调用函数。

Easy enough, 很容易,

class base_class {

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

class extended_class extends base_class{

    protected $reference;

    public function __construct($ref){
        $this->reference = $ref;
    }
}

Now this works fine obviously, 现在这显然很好,

But, when I am debugging I don't care about the value of $this->reference 但是,当我调试时,我不关心$this->reference的值

But, the object that $this->reference refers to is huge! 但是, $this->reference的对象是巨大的!

so, when I do print_r($instanceOfExtendedClass) I get the print out of that object. 所以,当我执行print_r($instanceOfExtendedClass)我得到了该对象的打印输出。

Now the reference is different for each class that extends base_class . 现在,对于扩展base_class每个类,引用是不同的。

What I wanted to do was just set reference as a static property on the extended_class class. 我想要做的只是将reference设置为extended_class类的静态属性。

But, then changing doSomethingWithReference to be self::$reference throws an undefined variable error. 但是,然后将doSomethingWithReference更改为self::$reference会抛出一个未定义的变量错误。

And conversely setting the static variable in base_class and modifying it from extended_class doesn't work as it changes the variable for all everything that extends from that class. 相反,在base_class设置静态变量并从extended_class修改它不起作用,因为它改变了从该类扩展的所有内容的变量。

Is there any way to do this so I don't get the print out of $this->reference ? 有没有办法做到这一点,所以我没有得到$this->reference的打印?

Because you are using PHP 5.3, you can use late static binding to resolve the static call to the right class at runtime. 因为您使用的是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;
    }

}

Big fat reminder : That one extended_class::$reference is going to be shared amongst all of the extended_class instances. 大胖提醒 :一个extended_class::$reference将在所有 extended_class实例之间共享。 If that is not what you intend, this is not going to work. 如果这不是你想要的,这是行不通的。

You seem to actually be worried about memory or resource use. 您似乎真的担心内存或资源使用。 In PHP, all objects are passed by reference. 在PHP中,所有对象都通过引用传递。 This means that passing an object as an argument, or creating a copy of it, etc, does not consume extra memory. 这意味着将对象作为参数传递或创建它的副本等不会消耗额外的内存。 If you need to reference an object in a number of other objects, doing so will not consume extra memory. 如果需要在许多其他对象中引用对象,那么这样做不会消耗额外的内存。


If I had extended_class and another identical class (say extended_class1) would they share the reference as well? 如果我有extended_class和另一个相同的类(比如extended_class1),他们也会共享引用吗? or would all extended_class' instances share one reference, while all extended_class1' instances would share another (the ideal case)? 或者所有extended_class'实例是否共享一个引用,而所有extended_class1'实例将共享另一个(理想情况)?

It looks like the sharing is based on where the static variable is defined. 看起来共享基于静态变量的定义位置。 Two examples, both from the PHP interactive prompt: 两个示例,都来自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

In this case, because the reference lives in the base class, everyone sees the same one. 在这种情况下,因为引用存在于基类中,所以每个人都看到相同的引用。 I suppose this makes some sort of sense. 我认为这有点道理。

What happens when we declare the reference with each child class.. most of the time? 当我们为每个子类声明引用时会发生什么...大部分时间?

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

Because 3 inherited from 1 without declaring it's own static property, it inherited 1's. 因为3继承自1而没有声明它自己的静态属性,所以它继承了1。 When we set 3's to Shared(3), it overwrote 1's existing Shared(1). 当我们将3设置为Shared(3)时,它覆盖了1的现有Shared(1)。

Conclusion: For this to work, the property needs to be declared in every class that needs the single unique reference. 结论:要使其工作,需要在需要单个唯一引用的每个类中声明属性。 Note that this code is valid as of 5.4.x. 请注意,此代码自5.4.x起有效。

Provide a way for the parent to access the child's static member: 为父级提供访问子级静态成员的方法:

<?php

abstract class base_class {
    abstract protected function reference();
    // If you want to be able to instanciate base class directly, use the following 2 lines in place of the previous 2 lines:
//class base_class {
    //protected function reference() {}

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

class extended_class extends base_class{
    protected static $reference;

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

    protected function reference(){
        return self::$reference;
    }
}

class ref {
    public function doSomething(){
        echo __METHOD__;
    }
}

$ref = new ref();
$ec = new extended_class($ref);
$ec->doSomethingWithReference();

print_r($ec);
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM