2011-07-13 126 views
10

我有一个API用于与我的Web应用程序交互,由类定义。每个可公开访问的方法在运行前都需要进行身份验证。而不是在每种方法中重复使用同一条线,我想使用magic __call函数。但是,它只能用于私有或受保护的方法,并且我需要公开才能使用Zend_Json_Server。__call相当于公共方法

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. 
    } 
} 

是否有可能钩到这些公共职能,并可能取消其执行被调用之前?

+0

您使用的是Zend ACL吗? –

+0

还没有。我不确定这个应用程序的这个部分是否合适。这是一个休息API,所以他们不登录并设置会话,而是传递一个令牌。 –

+1

什么是调用公共方法,并且该调用方可以调用身份验证方法? – webbiedave

回答

7

__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 
+0

这里的解决方案是使用代理的经典面向方面编程,并且正是您所需要的。我会质疑,因为'__call()'仅在方法不可访问并且所有公共方法都可访问时才被调用,所以'__call()'可以被认为不适用于公共方法。你让我兴奋,认为可能有我漏掉的漏洞,但可惜情况并非如此。 :( –

+0

或者重命名所有的函数来给这个名称添加一个'_',你可以调用方法'x',它将通过'__call',然后调用公共方法'x_'。它,一个装饰器可能会更容易:) – GolezTrol

+0

@大卫Harkness啊,谢谢 - 方面正是我要提到的另一件事,但我只能想到特质:)但是,你是正确的关于__call从那个角度。 –

3

既然你作为一个可能的解决方案我的意见去,我已经将它格式化为一个后人的答案:

如果面向方面或装饰解决方案不适合你,你可以尝试一个更基于框架的解决方案,通过将检查身份验证的代码放在你的公共方法的来电者甚至更高。

+1

我之前没有使用'Zend_Json_Server',但是它的接吻表亲'Zend_Controller_Action'定义了在实际操作方法之前调用的'preDispatch()'。也许JSON组件提供了这样的功能。 –

+0

不错的想法,@David,但Zend_Json_Server不会,它扩展Zend_Server_Abstract,它不会。 –

+0

感谢您使它成为@webbiedave的答案。这确实最终解决了这个特殊情况下的问题。 –