__call эквивалент для общедоступных методов
У меня есть API для взаимодействия с моим веб-приложением, определенным классом. Каждому общедоступному методу необходимо выполнить аутентификацию перед запуском. Вместо того, чтобы повторять одну и ту же строку в каждом методе, я хотел бы использовать магическую функцию __call. Тем не менее, он будет работать только на частных или защищенных методах, а мой должен быть общедоступным для работы с Zend_Json_Server.
class MY_Api
{
public function __call($name, $arguments)
{
//code here that checks arguments for valid auth token and returns an error if false
}
public function myFunction($param1, $param2, $param3)
{
//do stuff when the user calls the myFunction and passes the parameters
//this function must remain public so that Zend_Json_Server can parse it
//but I want it intercepted by a magic method so that the authentication
//can be checked and the system bails before it even gets to this function.
}
}
Можно ли подключиться к этим публичным функциям и, возможно, отменить их выполнение до их вызова?
Ответы
Ответ 1
__call
действительно работает для всех методов, включая общедоступные. Однако причина, по которой он не будет работать, если общедоступный метод уже существует, заключается в том, что код вне вашего класса уже может обращаться к публичным пользователям. __call
вызывается только для членов, которые недоступны вызывающему коду.
Насколько я знаю, на самом деле нет вариантов делать то, что вы ищете, за исключением использования какого-то шаблона декоратора:
class AuthDecorator {
private $object;
public function __construct($object) {
$this->object = $object;
}
public function __call($method, $params) {
//Put code for access checking here
if($accessOk) {
return call_user_func_array(array($this->object, $method), $params);
}
}
}
$api = new MY_Api();
$decoratedApi = new AuthDecorator($api);
//any calls to decoratedApi would get an auth check, and if ok,
//go to the normal api class' function
Ответ 2
Поскольку вы пошли с моим комментарием как возможное решение, я отформатировал его в ответ для потомков:
Если решения, ориентированные на аспекты или декорации, не сработают для вас, вы можете попробовать более основанное на каркасе решение, поместив код, который проверяет подлинность либо в вызывающем абоненте вашего общедоступного метода, либо даже выше.