你如何在PHP中的类中使用匿名函数?

时间:2015-06-15 19:32:34

标签: php anonymous-function

如何在此课程中拨打$greet?我使用的是PHP 5.5.4。

<?PHP   
class Model
{
    public $greet = function($name)
    {
        printf("Hello %s\r\n", $name);
    };
}

$test = new Model();
$test->greet('World');
$test->greet('PHP');
?>

Parse error: syntax error, unexpected '$greet' (T_VARIABLE), expecting function (T_FUNCTION)

也尝试了这个,

$test = new Model();
call_user_func($test->greet('World'));
call_user_func($test->greet('PHP')) 

匿名函数在类之外正常工作(直接来自manual)。

<?php
$greet = function($name)
{
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');
?>
编辑:我在电话中取出了美元符号(我抓住它就像一个答案开始滚动。它没有帮助,

call_user_func($test->greet('World'));
call_user_func($test->greet('PHP'));

编辑:

class Model
{
    public $greet;
    function __construct()
    {
        $this->greet = function($name)
        {
            printf("Hello %s\r\n", $name);
        };
    }
}

$test = new Model();
$test->greet('johnny');

现在我明白了,

Fatal error: Call to undefined method Model::greet() 

2 个答案:

答案 0 :(得分:2)

您无法使用表达式的结果初始化对象变量。仅允许静态/常量值。 e.g。

class foo {
   public $bar = 1+1; // illegal - cannot use an expression
   public $baz = 2; // valid. '2' is a constant
}

你必须这样做:

class foo {
   public $bar;
   function __construct() {
        $this->bar = function() { .... }
   }
}

根据this answer实际调用闭包:

$x = new foo()
$x->bar->__invoke();

答案 1 :(得分:2)

您调用greet这一事实使PHP将其视为函数而非属性。您可以在PHP中使用相同的属性和方法名称,因此区别是相关的。

作为一种解决方法,您可以使用__call()魔术方法。它将捕获对未定义的greet方法的调用。

class Model
{
    public $greet;
    function __construct()
    {
        $this->greet = function($name)
        {
            printf("Hello %s\r\n", $name);
        };
    }

    function __call($method, $args)
    {
        if (isset($this->$method) && $this->$method instanceof \Closure) {
            return call_user_func_array($this->$method, $args);
        }

        trigger_error("Call to undefined method " . get_called_class() . '::' . $method, E_USER_ERROR);
    }
}

$test = new Model();
$test->greet('johnny');

PHP7的更新

在PHP7中,由于Uniform Variable Syntax,不再需要__call()方法来调用绑定到属性的闭包。这将允许您在任何代码周围添加括号,就像在算术中一样。

class Model
{
    public $greet;
    function __construct()
    {
        $this->greet = function($name)
        {
            printf("Hello %s\r\n", $name);
        };
    }
}

$test = new Model();
($test->greet)('johnny');