Проект, над которым я работаю, содержит нечто вроде оболочки для call_user_func (_array), которая выполняет некоторые проверки перед выполнением. Одна из этих проверок – метод_exists (в том случае, если поставленный первый аргумент является экземпляром класса, а второй – именем метода). Другой is_callable. Функция будет генерировать исключение, если одна из этих проверок завершится с ошибкой.
Мой код содержит массив с именами функций (setFoo, setBar и т. Д.) И функцию php magic для перегрузки (__call), которая обрабатывает установку, замену и удаление определенных переменных (лучше некоторые элементы массива).
Проблема: method_exists вернет false, если функция не определена.
У меня есть шанс получить правду, если функция __call выполняет правильную обработку запроса?
__call
обрабатывает вызовы методов, которые не существуют. method_exists
– метод интроспекции, который проверяет существование метода.
Как можно определить метод обработки метода? Я думаю, что вы должны выбросить исключение вручную в __call
если не обрабатываете свой запрос и не поймаете исключение в коде, который в противном случае использовал бы method_exists
. Для этой цели существует BadMethodCallException
.
Посмотрите is_callable()
.
Но нет, если метод __call()
обрабатывает только некоторые имена, тогда вам понадобится другой способ проверить, будет ли вызов успешным.
Могу ли я предложить интерфейс с методом canCall($function)
или что-то еще? Затем проверьте, реализует ли класс интерфейс. Если это не так, просто используйте is_callable()
.
method_exists пробует две вещи:
function foo() {}
. get_method()
(C code) и если она вызывает ее, чтобы позволить реализации класса решить. Тебе понадобится последний. Но этот get_method()
не «расширен» для кода скрипта php, т. Е. Не существует способа позволить get_method () вызывать некоторый определенный пользователем код скрипта php (и что будет возвращать этот PHP-код?).
Поэтому ответ на мои лучшие знания: Нет, это невозможно (еще?).
Реализация ZEND_FUNCTION(method_exists)
может быть найдена в zend/zend_builtin_functions.c
и, я думаю, достаточно читабельна, даже если вы не знаете C, но PHP.
У меня method_exists
соблазн, возможно, использовать функции method_exists
в вашей функции __call
и throw
Exception
если это произойдет, и оберните все в блок catch
try
вместо использования функции is_callable
.
Если вы действительно уверены, что _call всегда имеет спад, вы можете сделать:
if (method_exists($this, $method_name) || method_exists($this, '__call')) { // Call of the method }