静的メソッドでターゲットクラスを検出する方法はありますか?
質問
以下はクラス階層とコードの例です。私が探しているのは、「ChildClass1」または「ChildClass2」に静的メソッド whoAmI() が呼び出されているかどうかを、各子クラスで再実装せずに判断する方法です。
<?php
abstract class ParentClass {
public static function whoAmI () {
// NOT correct, always gives 'ParentClass'
$class = __CLASS__;
// NOT correct, always gives 'ParentClass'.
// Also very round-about and likely slow.
$trace = debug_backtrace();
$class = $trace[0]['class'];
return $class;
}
}
class ChildClass1 extends ParentClass {
}
class ChildClass2 extends ParentClass {
}
// Shows 'ParentClass'
// Want to show 'ChildClass1'
print ChildClass1::whoAmI();
print "\n";
// Shows 'ParentClass'
// Want to show 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
解決 3
現在、PHP 5.3 は広く公開されているため、新しく利用可能な技術を反映するために、この質問に対する回答をまとめたいと思いました。
他の回答で述べたように、PHP 5.3 では 遅延静的バインディング 新しい経由で static
キーワード。また、新しい get_called_class()
クラスメソッド(インスタンスまたは静的)内でのみ使用できる関数も利用できます。
この質問で質問されたようにクラスを決定するために、 get_called_class()
関数は適切です:
<?php
abstract class ParentClass {
public static function whoAmI () {
return get_called_class();
}
}
class ChildClass1 extends ParentClass {
}
class ChildClass2 extends ParentClass {
}
// Shows 'ChildClass1'
print ChildClass1::whoAmI();
print "\n";
// Shows 'ChildClass2'
print ChildClass2::whoAmI();
print "\n";
の ユーザーが投稿したメモ get_called_class()
PHP 5.2 でも動作するサンプル実装がいくつか含まれています。 debug_backtrace()
.
他のヒント
あなたが言及しているのは既知のphpのバグだと思います。Php 5.3 は、新しい Late Static Binding 機能でこの問題に対処することを目指しています。
http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
クラスの識別は、よく理解されていないポリモーフィズムの症状であることがよくあります。
ChildClass1 と ChildClass2 のクライアントは、それらを区別する必要はありません。
どのクラスにも質問する場所はない someObject.whoAmI()
.
書きたい衝動に駆られたときはいつでも if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }
本当に追加する必要があります X()
さまざまな ChildClass のさまざまな実装を使用して、ParentClass にメソッドを追加します。
この種の「実行時の型識別」は、ほとんどの場合、適切な多態性のクラス設計に置き換えることができます。
PHP 5.3 以降では、以下を使用することで可能になります。 静的キーワード, しかし今のところそれは不可能です。
いいえ。PHP 5.3 を待ちます。