2015-02-08 6 views
1

Я пытаюсь запустить свойство $ 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 /> 

ответ

0

ОК, так что это работает, но почему мне нужно использовать call_user_func вообще? Это проблема с грамматикой PHP, почему-то у парсера возникают проблемы? У C++ была проблема с разбором <<, используемым с вложенными std::map s, и в то время было необходимо написать < <, чтобы избежать проблемы. Затем был введен трюк в грамматике для исправления проблемы. Я не понимаю, почему то же самое не может произойти в грамматике 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

Welcom to funny 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++, которые были проанализированы как операторы с битрейтом, но теперь это нормально с C++ 11.

+0

Да, я имел в виду закрытие '>>' vs. '>>', которое исправлено в C++ 11. Что касается кода, который вы опубликовали, это действительно показывает, что PHP - забавный язык. –