__call equivalent for public methods
I have an API for interacting with my web app, defined by a class. Each publicly accessible method needs to have authentication done before running. Rather than putting the same line over and over in each method, I'd like to use the magic __call function. However, it will only work on private or protected methods, and mine need to be public in order to work with 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开发者_StackOverflow社区_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.
}
}
Is it possible to hook into these public functions and possibly cancel their execution before they are called?
__call
actually works for all methods, including public. However, the reason it won't work if the public method already exists, is because code outside your class can already access the public members. __call
is only invoked for members which aren't accessible by the calling code.
As far as I know there are really no options to do what you're looking for, except by using some kind of a decorator pattern:
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
Since you went with my comment as a possible solution, I've formatted it into an answer for posterity:
If aspect-oriented or decorator solutions don't work for you, you can try a more framework-based solution by placing the the code that checks authentication either in the caller of your public method or even higher up.
精彩评论