将匿名函数分配给属性:从实例调用分配的函数失败

时间:2015-02-08 20:42:15

标签: php call anonymous-function anonymous anonymous-methods

我正在尝试运行Greeter类的$ greeter实例的$ greeter函数属性。我已经阅读了answers from this related post但是无法让它们工作(该帖子还提到了_call,traits,stdClass,从函数中返回一个函数(这对我来说没有意义,为什么这样做无需调用两次),给定的解决方案对于我想要实现的简单事情来说似乎有些过分。也许我的情况有点不同。我不明白为什么解析器搞砸了。

class Greeter {

  private $greeter;

  function __construct() {

    $this->greeter = function() {
      echo "Hello!\n";
    };

  }

  public function greet() {

    $this->greeter();

  }

}

// THIS WORKS AS EXPECTED:

$hello = function() { echo "Hi!\n"; };
$hello();

$greeter = new Greeter();

// NEITHER OF THESE WORK:

call_user_func($greeter->greet);

$greeter->greet();

$greeter['greet']();

输出:

Hi!

<br />
<b>Warning</b>:  call_user_func() expects parameter 1 to be a valid callback, no array or string given on line <b>30</b><br />
<br />
<b>Fatal error</b>:  Call to undefined method Greeter::greeter() on line <b>15</b><br />

2 个答案:

答案 0 :(得分:1)

好的,这样可行,但为什么我需要使用call_user_func呢?这是PHP语法的问题,由于某种原因解析器有问题吗? C ++用于解析与嵌套<<一起使用的std::map的问题,并且有时需要编写< <来避免此问题。然后引入语法中的技巧来解决问题。我不明白为什么在PHP语法中可能会发生同样的事情,使call_user_func变得不必要。

class Greeter {

  private $greeter;

  function __construct() {

    $this->greeter = function() {
      echo "Hello!\n";
    };

  }

  public function greet() {

    call_user_func($this->greeter);

  }

}

// THIS WORKS AS EXPECTED:

$hello = function() { echo "Hi!\n"; };
$hello();

$greeter = new Greeter();

// NOW THIS ALSO WORKS AS EXPECTED:

$greeter->greet();

答案 1 :(得分:1)

欢迎来到有趣的PHP。

<?php
    class A {
        public function f() {
            echo 'hi';
        }
    }

    $a = new A();

    $a->f(); // yes
    call_user_func($a->f); // no $a->f is not a func pointer in PHP
    call_user_func([$a, 'f']); // yes [$obj, $method_string] is callable
    $c = [$a, 'f'];
    $c(); // yes it's a callable

    [$a, 'f'](); // no PHP don't like that

    $c = function() use($a) { $a->f(); };
    $c(); // yes

    function() use($a) { $a->f(); }(); // no
    (function() use($a) { $a->f(); })(); // no

    // edit: there is more fun I forgot
    $m = 'f';
    $a->$m(); // yes

    $a->{'greet'}(); // yes

嗯,理解PHP有时做什么并不容易,但有很多情况下你不能写一个表达式。

empty($this->getNumber())或带有数组解除引用$this->getArray()[4]的旧版本相同。

顺便说一句,你的意思是在C ++模板中关闭>>> >,它们被解析为bitshift运算符,但现在可以用C ++ 11了。