Мне нужно , чтобы проверить, расширяет ли конкретный класс или реализует определенный интерфейс.
Обратите внимание , что имя класса является переменной строкой, т. Е. Выигралне может быть экземпляром этого класса.
Пользователи должны выбирать класс из списка классов, а система должна проверять, реализует ли класс определенный интерфейс или нет.Список классов является переменным (в соответствии с программным обеспечением 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
Этот последний тест показывает следующую ошибку:
Исправляемая фатальная ошибка: создание переменной 'Closure' не разрешено в C: \ Users \ abcdefghijklmn \ debug.php в строке XX
Вещи, которые я пытался:
- Использование
$obj=new @$obj();
: - ошибка скрыта, но она все еще выходит из строя / умирает. - Использование
try{}catch(){}
вокруг ошибочного блока: - Ничего не происходит - Использование
'class' instanceof 'class'
(где $ obj - строка): - безоговорочно возвращает false
Обратите внимание, что обязательная инициализация класса, используемая в этом методе ... отстой.Создание экземпляров означает ненужное потребление памяти, потерю скорости и большую склонность к ошибкам (представьте себе какой-нибудь странный класс, который при создании экземпляра без параметров продолжает уничтожать ваш жесткий диск;)).Так что, если есть какой-то другой способ, я бы просто хотел узнать об этом.
Редактировать: Это (надеюсь) окончательный код: -
/**
* 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;
}
}