对象属性似乎不作为变量函数?

时间:2015-09-07 14:45:32

标签: php

我在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中是否有解决方法? (没有闭包和匿名函数)。谢谢

3 个答案:

答案 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()方法