эквивалент вызова для общедоступных методов
У меня есть API для взаимодействия с моим веб-приложением, определенным классом. Перед запуском каждого общедоступного метода необходимо выполнить аутентификацию. Вместо того, чтобы ставить одну и ту же строку снова и снова в каждом методе, я хотел бы использовать функцию magic __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.
}
}
можно ли подключить эти публичные функции и, возможно, отменить их казнь до их вызова?
2 ответов
__call
фактически работает для всех методов, включая public. Однако причина, по которой он не будет работать, если открытый метод уже существует, заключается в том, что код вне вашего класса уже может получить доступ к открытым членам. __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
Так как вы пошли с моим комментарием в качестве возможного решения, я отформатировал его в ответ, для потомков:
Если решения, ориентированные на аспект или декоратор, не работают для вас, вы можете попробовать более рамочное решение, разместив код, который проверяет аутентификацию либо в вызывающем объекте вашего общедоступного метода, либо даже выше.