15

子クラスで参照されているクラスで関数を呼び出す必要がある基本クラスがあります。

簡単、

class base_class {

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

class extended_class extends base_class{

    protected $reference;

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

今、これは明らかにうまく機能します、

しかし、私がデバッグしているとき、私は$this->reference

しかし、$this->reference参照するオブジェクトは巨大です!

だから、私がそうするとき、私はprint_r($instanceOfExtendedClass)そのオブジェクトからプリントを取り出します。

これで、参照は、を拡張するクラスごとに異なりますbase_class

私がやりたかったのは、クラスreferenceの静的プロパティとして設定することだけでした。extended_class

ただし、に変更doSomethingWithReferenceするとself::$reference、未定義の変数エラーがスローされます。

逆に、静的変数をに設定しbase_classて変更するとextended_class、そのクラスから拡張されるすべての変数の変数が変更されるため、機能しません。

印刷物が出ないようにする方法はあります$this->referenceか?

4

2 に答える 2

24

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;
    }

}

重要なお知らせ: これはすべてのインスタンスextended_class::$referenceで共有されます。それが意図したものでない場合、これは機能しません。extended_class

あなたは実際にメモリやリソースの使用を心配しているようです。PHP では、すべてのオブジェクトが参照によって渡されます。これは、オブジェクトを引数として渡したり、そのコピーを作成したりしても、余分なメモリを消費しないことを意味します。他の多くのオブジェクト内のオブジェクトを参照する必要がある場合、それによって余分なメモリが消費されることはありません。


extended_class と別の同一のクラス (extended_class1 など) がある場合、それらも参照を共有しますか? または、すべての extended_class' インスタンスが 1 つの参照を共有し、すべての extended_class1' インスタンスが別の参照を共有しますか (理想的なケース)?

共有は、静的変数が定義されている場所に基づいているようです。PHP 対話型プロンプトからの 2 つの例:

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

この場合、参照は基底クラスに存在するため、全員が同じ参照を参照します。これは、ある意味当然だと思います。

ほとんどの場合、各子クラスで参照を宣言するとどうなりますか?

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

3 は自身の静的プロパティを宣言せずに 1 から継承したため、1 を継承しました。3 を Shared(3) に設定すると、1 の既存の Shared(1) が上書きされます。

結論: これが機能するには、単一の一意の参照を必要とするすべてのクラスでプロパティを宣言する必要があります。このコードは 5.4.x 以降で有効であることに注意してください。

于 2012-12-08T08:30:22.227 に答える
2

親が子の静的メンバーにアクセスする方法を提供します。

<?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);
?>
于 2012-12-08T05:34:49.387 に答える