我在php中处理示例代码,我读取了变量函数(类似于C中的函数指针)并开始编写下面的代码。看看这个
class fruit{
public $run;
}
function ano1(){
// some statements
}
$x = 'ano1'; // variable function
$x(); // works
$f = new fruit;
$f->run = 'ano1'; // lets store function to $run property
$f->run(); // call to undefined method why?
我认为原因
因为需要将$this
引用隐式传递给ano1()
,而ano1()
不是成员函数?所以使用$这在class fruit{
public : void (*run) ();
};
void ano1(){ cout << "im running" << endl; }
int main(){
fruit f;
f.run = ano1;
f.run(); // works as long as you dont use this
}
内无效,他们还没有实现呢?但是Iam是一个c ++背景,在c ++中非常有用:
.Text
或者PHP中是否有解决方法? (没有闭包和匿名函数)。谢谢
答案 0 :(得分:2)
它与C中的函数指针完全不同。
您看到的错误消息的特殊原因是PHP无法区分$fruit->run()
和$fruit->run()
之间的差异;也就是说,调用run
的方法$fruit
和调用任何函数名称$fruit->run
进行评估的区别。它在你期望的错误方面犯错误。您可以使用call_user_func($fruit->run)
消除歧义。
PHP没有像“函数指针”那样的东西。函数是PHP中的二等公民。 $x
只包含一个字符串,PHP支持传递函数的方法是按名称传递它们。当试图“调用一个字符串”时,PHP将检查是否有该名称的函数,并改为调用它。
所以你所做的只是将一个字符串分配给一个对象属性,但PHP的语法太模糊,不允许你从那里调用它。所有(使用任何 sane 代码)都不可能在事后将函数移植到对象上。必须在对象实例的类中定义所有对象方法。
答案 1 :(得分:1)
这是因为$f->run()
说“run
对象的$f
方法”。
相反,你可以这样做:
$str = $f->run;
$str();
调用字符串作为函数调用 或者
$f = new fruit;
$f->run = 'ano1';
call_user_func($f->run)
然后只调用属性run
作为方法
你可以......通过使用魔术方法__call
进行自动化的方式:
class Fruit {
public $run;
public function __call($methodName,$argsArray){
if (property_exists($this,$methodName)
&&is_callable($this->$methodName)){
return call_user_func_array($this->$methodName,$argsArray);
} else {
throw new \Exception("Method {$methodName} does not exist");
}
}
}
然后,你会这样做:
$fruit = new Fruit();
$fruit->run = 'ano1';
$fruit->run();
然后run
未在类Fruit
中定义,因此它将方法名称(运行)传递给__call
,并将您传递给run
的任何参数传递给Fruit
。然后,如果$methodName
具有名为call_user_func_array
的属性(在这种情况下&#39;运行&#39;),并且该属性可以作为函数调用,则使用WebServices
来调用它作为一种功能。
答案 2 :(得分:-1)
使用以下代码
$f->{$f->run}();
因为你正在对类fruit的对象上处理run()方法