2012-09-26 20 views
8

PHP 5.4.5, tutaj. Próbuję wywołać obiekt, który jest przechowywany jako członek innego obiektu. W ten sposób (bardzo z grubsza) można uzyskać błąd środowiska wykonawczego, ponieważ nie ma metody zwanej a. Ale jeśli piszę takie połączenie:Jak wywołać metodę __invoke dla zmiennej składowej wewnątrz klasy

($this->a)(); 

następnie pojawia się błąd składni.

Oczywiście, mogę napisać

$this->a->__invoke(); 

ale wydaje nieznośnie brzydki i raczej osłabia punkt funktorów. Właśnie zastanawiałem się, czy istnieje lepszy (lub oficjalny) sposób.

Odpowiedz

8
Nie

to trzy sposoby:

bezpośredniego wywoływania __invoke, które już wymienione:

$this->a->__invoke(); 

Poprzez przypisanie do zmiennej:

$a = $this->a; 
$a(); 

Korzystając call_user_func:

call_user_func($this->a); 

Ten ostatni prawdopodobnie jest tym, czego szukasz. Ma tę zaletę, że działa z każdym wywoływanym.

+1

Dzięki Igor. Spośród tych trzech, przypisanie do zmiennej wydaje się najbardziej jasne, ale żadne z nich nie jest bardzo miłe. Czy ktoś rozumie, dlaczego "oczywista" składnia $ this-> a() nie może znaleźć metody __invoke członka - dlaczego dostęp do elementu jest zasadniczo różny od składni nagich zmiennych? –

+1

Ponieważ jest niejednoznaczna. '$ this-> a()' może być metodą 'a' lub członkiem' $ a'. W PHP te dwa są dość mocno rozdzielone (w przeciwieństwie do JS na przykład). – igorw

+0

Ah. To ma sens. Dzięki. –

3

wiem, że to późna odpowiedź, ale użyć kombinacji __call() w jednostce dominującej i __invoke() w podklasie:

class A { 
    function __invoke ($msg) { 
    print $msg; 
    } 
} 

class B { 
    private $a; 

    public function __construct() { $this->a = new A(); } 

    function __call($name, $args) 
    { 
     if (property_exists($this, $name)) 
     { 
     $prop = $this->$name; 
     if (is_callable($prop)) 
     { 
      return call_user_func_array($prop, $args); 
     } 
     } 
    } 
} 

Następnie powinieneś być w stanie osiągnąć cukier syntaktyczny jesteś Szukam:

$b = new B(); 
$b->a("Hello World\n"); 
+0

To całkiem fajne podejście. Dzięki. –

2

FYI w PHP 7+ nawiasie wokół zwrotnego wewnątrz obiektu działa teraz:

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

    public function __invoke() {             
     echo "invoke!" . PHP_EOL;            
    }                   
}                    

(new foo)();                  

$f = new foo;                 
($f -> bar)(); 

Wynik:

invoke! 
bar! 
Powiązane problemy