2010-10-29 13 views
9

¿Hay alguna forma de que implícitamente declare las variables de nivel superior como globales para su uso en cierres?Cierres de PHP y ámbito de variable global implícita

Por ejemplo, si se trabaja con código como este:

$a = 0; //A TOP-LEVEL VARIABLE 

Alpha::create('myAlpha') 
    ->bind(DataSingleton::getInstance() 
     ->query('c') 
    ) 
    ->addBeta('myBeta', function($obj){ 
     $obj->bind(DataSingleton::getInstance() 
       ->query('d') 
      ) 
      ->addGamma('myGamma', function($obj){ 
       $obj->bind(DataSingleton::getInstance() 
         ->query('a') 
        ) 
        ->addDelta('myDelta', function($obj){ 
         $obj->bind(DataSingleton::getInstance() 
          ->query('b') 
         ); 
        }); 
      }) 
      ->addGamma('myGamma', function($obj){ 

       $a++; //OUT OF MY SCOPE 

       $obj->bind(DataSingleton::getInstance() 
         ->query('c') 
        ) 
        . 
        . 
        . 

Los cierres son llamados desde un método como tal:

public function __construct($name, $closure = null){ 
     $this->_name = $name; 
     is_callable($closure) ? $closure($this) : null; 
    } 

Así que en resumen/TL; DR, es allí una forma de declarar implícitamente variables como globales para su uso en cierres (u otras funciones, supongo) sin hacer uso de la palabra clave global o $GLOBALS superglobal?

empecé este tema en otro foro que frecuento (http://www.vbforums.com/showthread.php?p=3905718#post3905718)

Respuesta

31

Usted tiene que declarar en la definición de cierre:

->addBeta('myBeta', function($obj) use ($a) { // ... 

lo contrario, debe utilizar la palabra clave global. Debe hacer esto para cada cierre que use $a también.

+7

Tenga en cuenta que 'use' hereda variables del ámbito primario solamente. En un escenario en el que los cierres no están definidos en el alcance global, igual tendría que usar la palabra clave 'global' en su lugar. Sin embargo, debería funcionar para el escenario del OP. – Gordon

+0

Hmm, tenía miedo de que fuera 'uso'. Es de esperar que este problema no prevalezca en el sistema que estoy desarrollando, ya que la mayoría de las llamadas * globales * probablemente se realizarán en instancias estáticas. Estoy tratando de jugar con un truco que involucra 'extract()' en '$ GLOBALS' y' call_user_func_array() '... – Dan

+5

Además,' $ a ++ 'como se muestra en el ejemplo del OP no se aplicará de nuevo a la global '$ a' a menos que se use como referencia, por ejemplo,' & $ a'. Los objetos se usan por referencia. – Gordon