【问题标题】:How does __call() magic function exactly work in PHP?__call() 魔术函数在 PHP 中是如何工作的?
【发布时间】:2014-03-05 10:09:15
【问题描述】:

我有一个名为 $obj 的对象。我已经覆盖了该类的__call 函数,因此当我调用$obj->setVariableName($value) 时会发生这种情况:$obj->variableName = $value。我不知道项目中何时以及如何准确地调用$obj->setVariableName($value)。因此,在运行应用程序期间会发生这种情况:

setVariable1($value) : works!
setVariable2($value) : works!
setVariable3($value) : It won't trigger __call()
setVariable4($value) : works!

当我编写额外的函数setVariable3 时,它就可以工作了。不知道setVariable3是怎么调用的,是直接被$obj->setVariable3调用还是用call_user_func_array这样的函数调用。

__call 不适用于setVariable3 可能是什么问题?

更新:现在我知道 setVariable3 是从 $form->bind($user) 调用的,并且运行 $user->setVariable3('foo') 有效。 (这是一个ZF2+Doctrine项目)

【问题讨论】:

  • 不可能这样。另外,你为什么用这种奇怪的方式使用__call()? Setters (so __set()) 正是您正在寻找的功能
  • __set 是我想运行$obj->variableName = $value 的时间。在这种情况下,我无权访问它的调用方式。事实上,在这种情况下,我知道代码中的某处 $obj->setVariable3($value) 被调用,我需要为它定义函数。
  • 由于您不清楚变量的设置位置/方式,因此第一个调用端口可能是调查调用代码。为了帮助您识别调用代码,请使用debug_backtrace 函数。见 - bd1.php.net/debug_backtrace
  • var_dump(debug_backtrace());给了我大量的数据,我用的是ZF2+Doctrine
  • @MostafaShahverdy 您应该通过过滤数据或仅输出您感兴趣的级别仅输出调用者 - stackoverflow.com/a/190426/1603275

标签: php magic-function


【解决方案1】:

听起来很奇怪,但对我有用。

class test {
    public function __call($method, $args)
    {
        printf("Called %s->%s(%s)\n", __CLASS__, __FUNCTION__, json_encode($args));
    }
}
$test = new test();
$value = 'test';
$test->setVariable1($value);
$test->setVariable2($value);
$test->setVariable3($value);
$test->setVariable4($value);

将输出:

Called test->__call(["test"])
Called test->__call(["test"]) 
Called test->__call(["test"]) 
Called test->__call(["test"])

只有当你试图访问不可访问的属性时,才会调用 __set。例如

class test {
    public function __set($var, $value) {
        printf("Called %s->%s(%s)\n", __CLASS__, __FUNCTION__, json_encode(func_get_args()));
    }
}
$test = new test();
$value = 'test';
$test->callMagicSet = $value;

将导致:

Called test->__set(["callMagicSet","test"])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 2011-06-02
    • 2018-09-17
    相关资源
    最近更新 更多