PHP __call vs method_exists

Проект, над которым я работаю, содержит нечто вроде оболочки для call_user_func (_array), которая выполняет некоторые проверки перед выполнением. Одна из этих проверок – метод_exists (в том случае, если поставленный первый аргумент является экземпляром класса, а второй – именем метода). Другой is_callable. Функция будет генерировать исключение, если одна из этих проверок завершится с ошибкой.

Мой код содержит массив с именами функций (setFoo, setBar и т. Д.) И функцию php magic для перегрузки (__call), которая обрабатывает установку, замену и удаление определенных переменных (лучше некоторые элементы массива).

Проблема: method_exists вернет false, если функция не определена.

У меня есть шанс получить правду, если функция __call выполняет правильную обработку запроса?

Solutions Collecting From Web of "PHP __call vs method_exists"

__call обрабатывает вызовы методов, которые не существуют. method_exists – метод интроспекции, который проверяет существование метода.

Как можно определить метод обработки метода? Я думаю, что вы должны выбросить исключение вручную в __call если не обрабатываете свой запрос и не поймаете исключение в коде, который в противном случае использовал бы method_exists . Для этой цели существует BadMethodCallException .

Посмотрите is_callable() .

Но нет, если метод __call() обрабатывает только некоторые имена, тогда вам понадобится другой способ проверить, будет ли вызов успешным.

Могу ли я предложить интерфейс с методом canCall($function) или что-то еще? Затем проверьте, реализует ли класс интерфейс. Если это не так, просто используйте is_callable() .

method_exists пробует две вещи:

  • Ищет имя метода в таблице функций класса. Это методы типа function foo() {} .
  • Проверяет, имеет ли класс (код C) 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 }