此代码不起作用:
class A {
public function b() {
(new B)->d([$this, 'c']); // Error is here
}
private function c() {
echo 'test';
}
}
class B {
public function d($e) {
call_user_func($e);
}
}
(new A)->b();
运行此代码会给出:
call_user_func()[...]无法访问私有方法A :: c()
我能理解为什么它不起作用。但我不知道真正的原因。在A::b()
中,我处于A
上下文中,这就是为什么我认为c()
可以被调用($this
众所周知且做指的是A
,所以我在A
上下文中。
对我来说真正奇怪的是,如果我更换它会起作用:
(new B)->d([$this, 'c']);
人:
(new B)->d(function() { $this->c(); });
所以现在调用私有函数不是问题。我不明白为什么。而且我没有在文档中找到任何关于此的内容。
当我致电(new B)->d(function() { $this->c(); });
时,为什么(new B)->d([$this, 'c']);
有效但有(new A)->b();
?
答案 0 :(得分:1)
当您使用[$this, 'c']
时,数组以索引[0]
作为对象A的对象和索引[1]
的引用作为字符串c传递,因此它尝试使用存储在数组索引d
中的字符串从方法[1]
调用该函数。
当您直接传递函数时,会传递closure并绑定到类A
,因此可以将其用于调用函数c
,因为它绑定到类A
}。
然而你也可以使用第一种方法而不是通过这样的小技巧得到任何错误:
class A {
public function b() {
(new B)->d([$this, 'c']);// NO ERROR NOW!
}
private function c() {
echo 'test';
}
}
class B {
public function d($e) {
// Here is the trick :
$f = function() { $this->c(); };
$f = Closure::bind($f, $e[0], 'A');
$f();
}
}
(new A)->b();
我所做的是创建一个闭包,然后使用$e[0]
中使用import os
os.system("crontab -l | sed '/^\*.*heightSQL.py/s/^/#/' | crontab -")
中收到的对象引用将::bind绑定到A类。
答案 1 :(得分:0)
我说如果你使用:
$this->c();
它会在那里被执行,所以来自具有此功能的A类。 如果你这样做:
[$this, 'c']
你传递了应该由B类执行的类和函数,它也将由B类执行,但是B类不能访问A类的私有函数。
此致