2009-11-01 14 views
5

Tengo una clase Logger que, entre otras cosas, tiene un método Log.
Como Log es el uso más común de la Logger ejemplo, tengo cable __invoke llamar LogObjeto llamable de PHP como miembro de objeto

Otra clase, "Sitio" contiene un miembro de "registro", una instancia del Registrador.

¿Por qué este trabajo:

$Log = $this->Log; 
$Log("Message"); 

Pero no esto:

$this->Log("Message"); 

El primero falla con "error fatal de PHP: Llamada a indefinido Sitio método :: Log()" ¿Es
esto es una limitación de la implementación del objeto invocable, o estoy malentendiendo algo?

Respuesta

1

mismas razones no se puede hacer esto:

$value = $this->getArray()["key"];

o incluso esta sintaxis

$value = getArray()["key"];

Dado que PHP no hace corta la mano muy bien.

+0

Principalmente debido a la escritura suelta. No hay forma de inferir realmente lo que podría querer decir, por lo que de manera predeterminada se trata de errores al principio. –

+0

He escrito un pre-examinador impar que permite escribir tales expresiones: http://code.google.com/p/php-preparser/ :) (¿Puedo "publicitar" mis soluciones de código abierto aquí?) –

+5

Este ejemplo ya no es relevante, esta sintaxis funciona ahora. –

1

Esto puede funcionar:

${this->Log}("Message"); 

Pero quizás es más fácil y mejor utilizar la llamada completa? No parece haber una manera de obtener lo que desea trabajar en una línea.

El error en su pregunta indica que está buscando una función definida en la clase que no existe. Un objeto invocable no es una función, y parece que no se puede tratar como uno en este caso.

+0

no funcionará (al menos no para mí con php 5.3) »inesperado T_OBJECT_OPERATOR ...« – knittl

7

Desafortunadamente, esta es (todavía) una limitación de PHP, pero tiene sentido cuando lo piensas, ya que una clase puede contener propiedades y métodos que comparten nombres. Por ejemplo:

<?php 
class Test { 
    public $log; 

    public function __construct() { 
     $this->log = function() { 
      echo 'In Test::log property'; 
     }; 
    } 

    public function log() { 
     echo 'In Test::log() method'; 
    } 
} 

$test = new Test; 
$test->log(); // In Test::log() method 
call_user_func($test->log); // In Test::log property 
?> 

Si PHP permitiera la sintaxis que desea, ¿qué función se invocaría? Desafortunadamente, eso solo nos deja con call_user_func[_array]() (o copiando $this->log a otra variable e invocando eso).

Sin embargo, sería bueno si la sintaxis siguiente era aceptable:

<?php 
{$test->log}(); 
?> 

Pero, por desgracia, no lo es.

+0

Esto es un capricho extraño de hecho. Algo como ($ test-> log)() parece ser una limitación del analizador, no del lenguaje en sí. –