PHP __call против method_exists - PullRequest
       5

PHP __call против method_exists

14 голосов
/ 01 октября 2009

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

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

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

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

Ответы [ 5 ]

8 голосов
/ 01 октября 2009

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

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

5 голосов
/ 01 октября 2009

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

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

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

4 голосов
/ 01 октября 2009

method_exists пытается две вещи:

  • Ищет имя метода в таблице функций класса. Это методы типа function foo() {}.
  • Проверяет, имеет ли класс (код C) функцию (код C) get_method() и вызывает ли она ее, чтобы позволить реализации класса принять решение.

Вам понадобится последний. Но это get_method() не «расширено» на код сценария php, т. Е. Нет способа позволить get_method () вызвать некоторый определенный пользователем код сценария php (и что вернет этот код php?).

Так что ответ, насколько мне известно, таков: нет, это невозможно (пока?).

Реализацию ZEND_FUNCTION(method_exists) можно найти в zend/zend_builtin_functions.c, и я думаю, что она достаточно читабельна, даже если вы не знаете C, но PHP.

1 голос
/ 10 августа 2015

Если вы действительно уверены, что _call всегда имеет запасной вариант, вы можете сделать:

if (method_exists($this, $method_name) || method_exists($this, '__call')) {
  // Call of the method
}
1 голос
/ 10 июня 2010

У меня может возникнуть желание использовать method_exists в вашей функции __call и throw и Exception в случае неудачи и обернуть все в блок try catch вместо использования is_callable функция.

...