3

特定のクラスが特定のインターフェイスを拡張または実装しているかどうかを確認する必要があります。

クラス名は可変文字列であることに注意してください。つまり、このクラスのインスタンスはありません。

ユーザーはクラスのリストからクラスを選択することになっており、システムはそのクラスが特定のインターフェースを実装しているかどうかをチェックすることになっています。クラスのリストは可変であり(現在実行中の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;
    }
}
4

2 に答える 2

2

代わりにPHPのReflectionClassを使用してみてください。

$rc = new ReflectionClass($obj);
return $rc->implementsInterface($cls);
于 2010-12-06T10:58:59.270 に答える
0

ReflectionClassを使用します。

function is_instance_of($obj,$cls){
    $ref=new ReflectionClass($obj);
    return in_array($cls, array_keys($ref->getInterfaces());
}
于 2010-12-06T10:58:02.287 に答える