Одну вещь, которую я часто вижу, когда просматриваю чужой код на php, это не правильное использование функции method_exists(), и это требует немного разъяснений.
Это типичный пример того, о чем я тут говорю
if (method_exists($object, 'SomeMethod')){ $object->SomeMethod($this, TRUE); }
Цель у этого куска кода довольно проста - понять: имеет ли некий объект (переменная $object) метод с названием SomeMethod, если так то вызвать его, подав несколько аргументов на вход
Да, но...
Этот код будет, вероятно, работать очень хорошо в течение всей своей жизни, но что если метод объекта будет не видим в текущем положении (к примеру метод private или protected)? PHP функция method_exists() делает следующее: она проверяет если класс или объект имеет метод исходя из того, что метод будет вызван внутри самого объекта. И вернет true если это так, или false если нет. Т.е. видимость метода, в конкретном применении вообще не проверяется. Поэтому, если вы используете private или protected методы, то такая проверка вернет true, но когда вы попытаетесь вызвать такой код, то увидите следующую ошибку
“Fatal error: Call to private method…”, immediately terminating the current script execution.
Правильный инструмент для правильной работы
Реальная цель предыдущего кода, была в том, чтобы определить, может ли данный метод быть вызван в данном контексте
Поэтому верно будет использовать is_callable() функцию php
Как это работает?
is_callable() получает на вход callback как первый аргумент, который, в нашем случае, является массивом и содержит два занчения: первое из которых - это объект (ну или название класса в виде строки), а второй содержит имя метода. is_callable() вернет TRUE когда метод будет доступен в данном контексте
if (is_callable(array($object, 'SomeMethod'))){ $object->SomeMethod($this, TRUE); }
Следующий кусок кода илюстрирует разницу между работой двух функций method_exists() и is_callable() в действии:
class Foo { public function PublicMethod() {} private function PrivateMethod() {} public static function PublicStaticMethod() {} private static function PrivateStaticMethod() {} } $foo = new Foo(); $callbacks = array( array($foo, 'PublicMethod'), array($foo, 'PrivateMethod'), array($foo, 'PublicStaticMethod'), array($foo, 'PrivateStaticMethod'), array('Foo', 'PublicMethod'), array('Foo', 'PrivateMethod'), array('Foo', 'PublicStaticMethod'), array('Foo', 'PrivateStaticMethod'), ); foreach ($callbacks as $callback) { var_dump($callback); var_dump(method_exists($callback[0], $callback[1])); // 0: object / class name, 1: method name var_dump(is_callable($callback)); echo str_repeat('-', 40), "\n"; }
Запустите это, и вы увидите, что все тесты вернули true при использовании method_exists(), даже private методы, тогда как is_callable() вернул FALSE
Больше деталей
is_callable() нужно использовать, когда нужно проверить - может ли быть вызван тот или иной метод в данном контексте, и совершенно ничего не говорит, о том, есть ли такой метод в определении класса
кроме того, если проверяемый класс, имеет реализацию метода __call() тогда is_callable() вернет true для любых, даже не существующих методов. А method_exists() вернет false;
Все остальное вы можете узнать, в PHP документации.
Комментарии
будто бы я админ!
я думаю случилось ошибка! свяжитесь со мной
ПСЫ
не нашел контактов
Совсем нет кода в статье, поправьте, плз.