2012-12-08 10 views
10

私は子クラスで参照されるクラスの関数を呼び出す必要がある基本クラスを持っています。親クラスから子クラスの静的変数にアクセスしますか?

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クラスの静的プロパティとして設定されました。

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

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

これを行う方法はありますか?$this->referenceからプリントアウトしないでください。

+2

どのPHPバージョンを使用していますか? 5.3の静的な振る舞いにはいくつかの大きな変更がありました。http://php.net/language.oop5.late-static-bindingsを参照してください。非常に異なる答え。 – Charles

+1

PHPバージョン5.3 – Hailwood

+0

このクラス構造は何かに違反し、私はそれが何であるか分かりません:) –

答えて

14

あなたはPHP 5.3を使用しているため、実行時に正しいクラスへの静的呼び出しを解決するためにlate static bindingを使用することができます。

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

} 

ビッグファットリマインダー:1 extended_class::$referenceextended_classインスタンスのすべて間で共有される予定であること。それがあなたが意図するものでないなら、これはうまくいかないでしょう。

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


私はextended_classと別の同一クラスを持っていた場合(たとえばextended_class1)彼らは同様の参照を共有するのでしょうか?またはすべてのextended_class 'インスタンスは1つの参照を共有しますが、すべての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 

、基本クラスの参照の生活は、誰もが同じものを見ているので。これは何らかの意味があると思います。

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

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以降で有効です。

+0

私は実際にメモリを心配していません、それは単にデバッグのためです、私は〜600行(コードイグナイターオブジェクト!)をスクロールするのが好きではないオブジェクトのプロパティが何であるかを見てください!参照を共有する 'extended_class :: $ reference'についてのあなたの意見は、もし私が' extended_class'と別の同じクラス( 'extended_class1'と言う)を持っていれば、それらも参照を共有しますか?すべての 'extended_class1'インスタンスが別の(理想的な場合)を共有するのに対し、すべての' extended_class'インスタンスは1つの参照を共有しますか? – Hailwood

+0

@Hailwood、静的プロパティがどこで解決されたかを示すテストで私の答えを更新しました。 – Charles

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); 
?> 
+2

-1、これは単なるコードダンプです。あなたはこのコードが何であるか、なぜそれが機能するのか、どのように動作するのか、どのように答えられるのか説明していません。 – Charles

+2

批判のおかげで、@チャーレス - 意図された皮肉。実際には、あなたのコメントに+1してください。将来的には、もっと冗長で、コードを読むだけで何が起こっているのかを読者が理解できるとは確信しません。私はPHPが5.3未満の箱を持っていませんが、この例は遅い静的バインディングなしで固まっているものに対してはうまくいくと思います。私がそれがより小さなバージョンで動作することを確認したら、私は答えを更新して、さよならを説明し、この答えはPHP <5.3のユーザーにとって価値があると述べます。 –

関連する問題