__call эквивалент для открытых методов - PullRequest
10 голосов
/ 14 июля 2011

У меня есть 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.
  }
}

Можно ли подключиться к этим открытым функциям и, возможно, отменить их выполнение до того, как ониназываются?

Ответы [ 2 ]

7 голосов
/ 14 июля 2011

__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
3 голосов
/ 14 июля 2011

Поскольку вы выбрали мой комментарий как возможное решение, я отформатировал его в ответ для потомков:

Если аспектно-ориентированные или декораторские решения у вас не работают, вы можете попробовать более основанное на фреймворке решение, поместив код, проверяющий аутентификацию, либо в вызывающую функцию вашего открытого метода, либо даже выше.

...