假设我们有一个带有几种 protected 和/或公共(public)方法的类。
每次调用方法时,我都需要执行检查。每当我调用一个方法时,我都可以进行检查:

class Object
{
    // Methods
}

$o = new Object();

if($mayAccess) $o->someMethod();

或者
if($mayAccess) $this->someMethod();

但是我希望开发人员既不必考虑它,也不必编写它。我已经考虑过使用__call来做:
class Object
{
    public function __call($methodName, $args)
    {
        if($mayAccess) call_user_func_array($this->$methodName, $args);
    }
}

不幸的是,如果我从类内部调用该方法,则__call将不会被调用,因为它仅在调用非可见方法时才起作用。

有没有一种干净的方法可以隐藏内部和外部调用的此检查?同样,目标是确保开发人员在调用方法时不会忘记这样做。

提前致谢 :)
EDIT :

我有另一种方法可以做到这一点:
class Object
{
    public function __call($methodName, $args)
    {
        if($mayAccess) call_user_func_array($methodName, $args);
    }
}

function someMethod() { }

但是我将无法再使用$ this,这意味着我确实不需要任何 protected 方法。

最佳答案

不,我不这么认为。不过,您可以做的是编写proxy:

class MayAccessProxy {

    private $_obj;

    public function __construct($obj) {
        $this->_obj = $obj;
    }

    public function __call($methodName, $args) {
        if($mayAccess) call_user_func_array(array($this->_obj, $methodName), $args);
    }
}

这意味着您必须为要检查的每个对象实例化一个代理:
$obj = new MayAccessProxy(new Object());
$obj->someMethod();

当然,您还希望代理的行为与对象本身完全一样。因此,您还必须定义其他魔术方法。

为了使开发人员更容易一点,您可以执行以下操作:
class Object {

    /**
     * Not directly instanciable.
     */
    private __construct() {}

    /**
     * @return self
     */
    public static function createInstance() {
        $obj = new MayAccessProxy(new self());
        return $obj;
    }
}

$obj = Object::createInstance();

关于PHP-一直通话,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13534269/

10-10 03:25