Как использовать is_callable с __call?

Я использую PHP 5.3, в котором введены замыкания. Поскольку теперь у меня есть замыкания, доступные во всем моем приложении (и фреймворке), я использую is_callable, чтобы увидеть, что это за обработчик $callback.

Если $callback is_callable, я знаю достаточно и использую эту функцию/метод/замыкание. Если он не вызывается и является строкой, вероятно, это имя метода в классе $this. Он может существовать, а может и нет. Если я допущу это до PHP, он «выдаст» хорошую фатальную ошибку (мне это нравится).

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

Теперь проблема заключается в полезности is_callable, потому что после реализации __call все вернет true, потому что у всего есть запасной вариант (будучи __call).

Есть ли способ иметь как динамические методы, так и полезные is_callable?

Что бы я хотел увидеть, так это какой-то кешируемый магический метод __is_callable, с которым PHP будет «консультироваться» при вызове is_callable(array($object, $method)).

На php.net я не могу найти никого, кто был бы так огорчен этим, как я. Этого не может быть! Если вы используете __call, вы больше не можете использовать is_callable!?

Я имею какой-то смысл?

PS. Я изучил method_exists, но этого недостаточно (даже если я смогу отфильтровать все замыкания и глобальные функции), потому что он вернет true для частных и защищенных методов, а также для общедоступных.

изменить
Я сделал "лучший" is_callable, который проверяет наличие примесей, но я думаю, что это довольно дорого.


person Rudie    schedule 09.05.2011    source источник


Ответы (1)


Первая идея: как насчет проверки существования метода в get_class_methods()? Эта функция заботится о проблемах с областью действия.

Вторая идея: если функция, которую вы ищете, не существует в классе, вы также можете проверить (используя method_exists), содержит ли класс __call магический метод, если он не вызывает, очевидно, вызов несуществующей функции является незаконным. Если класс содержит метод __call, скорее всего, вызывающая сторона знает, что делает.

Это только мои мысли, я предполагаю, что Python лучше в таких вещах.

person Dr McKay    schedule 09.05.2011
comment
get_class_methods действительно решил другую проблему, но не примеси. Эта очень важная часть на самом деле неверна: если класс содержит метод __call, вполне вероятно, что вызывающий объект знает, что он делает. потому что вы можете установить средство визуализации для 10 классов, которые есть (и используют) только у 4 классов, а остальные 6 будут использовать стандарт, но вам нужно установить его только один раз. (Вау, ты понял?) - person Rudie; 09.05.2011