特定のクラスが特定のインターフェイスを拡張または実装しているかどうかを確認する必要があります。
クラス名は可変文字列であることに注意してください。つまり、このクラスのインスタンスはありません。
ユーザーはクラスのリストからクラスを選択することになっており、システムはそのクラスが特定のインターフェースを実装しているかどうかをチェックすることになっています。クラスのリストは可変であり(現在実行中のPHPソフトウェアによる)、これらのクラスの一部は初期化できますが、他のクラスは初期化できません。
これが私が使用しているコードです:
function is_instance_of($obj,$cls){
if(is_string($obj))$obj=new $obj();
if(PHP_MAJOR_VERSION>4)return $obj instanceof $cls;
if(PHP_MAJOR_VERSION>3)return is_a($obj,strtolower($cls));
return false;
}
var_dump(is_instance_of('MyClass','IMyInterface')); // in theory, true
var_dump(is_instance_of('Closure','IMyInterface')); // FATAL ERROR
その最後のテストでは、次のエラーが表示されます。
キャッチ可能な致命的なエラー:「クロージャ」のインスタンス化は、XX行のC:\ Users \ abcdefghijklmn\debug.phpでは許可されていません
私が試したこと:
- 使用
$obj=new @$obj();
:-エラーは非表示になっていますが、それでも障害/停止します。 - 問題のあるブロックの周りを使用
try{}catch(){}
する:-何も変わりません - 使用
'class' instanceof 'class'
($ objは文字列):-false
無条件に戻ります
このメソッドで使用される必須のクラス初期化は...sucksであることに注意してください。インスタンスを作成すると、不要なメモリ消費、速度の低下、エラーが発生しやすくなります(パラメータなしでインスタンス化すると、HDDが破壊されるという奇妙なクラスを想像してみてください;))。ですから、他に方法があれば、私はそれについて知りたいだけです。
編集:これは(うまくいけば)最終的なコードです:-
/**
* Cross-version instanceof replacement.
* @param object $obj The instance to check.
* @param stirng $cls The class/interface name to look for.
* @return boolean Whether an object extends or implements a particular class
* or interface.
* @link http://stackoverflow.com/questions/4365567/php-instanceof-over-strings-and-non-initializable-classes
*/
function is_instance_of($obj,$cls){
if(is_string($obj) || PHP_MAJOR_VERSION>4){
$rc=new ReflectionClass($obj);
return $rc->implementsInterface($cls);
}else{
if(PHP_MAJOR_VERSION>3)return is_a($obj,strtolower($cls));
return false;
}
}