2011-04-21 17 views
5

Esta es más una pregunta sobre por qué entonces 'cómo hacerlo', sin embargo, me ha estado molestando por algunos días. Actualmente estoy haciendo un trabajo con CodeIgniter y volviendo a PHP temporalmente de Ruby, me molesta sobre la siguiente magia de alcance.PHP, un ámbito de variable impar?

<?php $query = $this->db->get('articles', 2); 
     if ($query->num_rows() > 0) 
     { 
      foreach ($query->result_array() as $row) 
      { 
       $data[] = $row; # <-- first appearance here 
      } 
     return $data; # <--- :S what?! 
     } 

Como se puede ver, no soy exactamente un gurú de PHP, sin embargo, la idea de que me molesta ámbito local que fuera del bucle foreach la variable está 'disponible'. Así que he intentado esto en el interior de una vista:

<?php 

    if($a==1) 
    { 
    $b = 2; 
    } 
    echo $b; 
?> 

que dan como resultado un mensaje de error:

Message: Undefined variable: b 

El manual de PHP dice acerca de la determinación del alcance local, aún sigo preguntando por qué sucede esto y si hay son reglas especiales que no conozco. Y me da miedo :)

gracias por compartir ideas,

+2

de crear la variable en el segundo ejemplo sólo si se 1. Desde $ A no existe (PHP realidad genera un error aquí), no se creará un $ $ b. En el primer ejemplo, se han cumplido todas las condiciones, por lo que $ data se crea y se usa como valor de retorno. –

+0

El segundo ejemplo es más una aclaración/simplificación excesiva que $ b fuera de las llaves es accesible; como otras respuestas dicen, las llaves no definen el alcance de las variables. Y eso, no sabía :) – Shyam

+0

Creo que esto está desactualizado ahora, o es una cuestión de ESTRICTAD tal vez. Su segundo ejemplo funciona para mí e imprime 2. Estoy trabajando con 5.4.16 con STRICT desactivado – Dennis

Respuesta

11

Solo las funciones crean un nuevo alcance local. Las llaves por sí mismas no. Las llaves son solo una construcción auxiliar para otras estructuras de lenguaje (if, while o foreach).

Y dondequiera que acceda a cualquier variable en un ámbito local no importa. El ámbito local es diccionario implícito detrás de las escenas (ver get_defined_vars). Puede obtener un aviso de depuración accediendo a variables previamente indefinidas, pero eso es todo.

En su ejemplo específico, parece que solo está operando en el ámbito global.

+1

¡Esa primera oración hace que sea muy claro! ¡Gracias! – Shyam

+0

Cool. También hay un término de semántica del lenguaje formal para eso, pero no puedo recordarlo. :/ – mario

+0

@mario, [cita requerida] (http://xkcd.com/285) para "* Las llaves son sólo una construcción auxiliar ** ** para otras estructuras de la lengua *" .... – Pacerier

7

foreach no crea ningún ámbito de las variables en PHP por lo que es natural, si la variable está disponible fuera foreach

para la segunda cuestión, el $a no es igual a 1, por lo tanto, $b no se inicializa y lanza un aviso cuando se accede al exterior. Si asigna el valor 1 a $a y lo prueba, se sorprenderá de que los avisos hayan desaparecido.

Aquí no hay nada como el alcance.

+0

El segundo ejemplo no es una pregunta, más como una perspectiva como esperaría comportamiento (mi inexperiencia con el lenguaje PHP). Como dicen otras respuestas, las llaves no definen el alcance de la variable. A pesar de que, gracias por su respuesta :) – Shyam

+0

@shyam: No hay problema, Como he intentado explicar este –

1

Shyam, está utilizando un lenguaje de scripting, no C++. Es típico que los lenguajes de script como PHP o JavaScript no tengan diferentes ámbitos para cada bloque de código. En cambio, hay un alcance para toda la función. Esto es realmente útil si considera su primer ejemplo, pero obviamente debe tener cuidado, como se puede ver en el segundo.

+1

Es un buen diseño para PL para incluir mecanismos de alcance (además de la fea 'call_user_func (function() {}) '). ¿Por qué es "típico que los lenguajes de script no tengan diferentes ámbitos para cada bloque de código"? – Pacerier

1

es $ a es igual a 1? ¡Si no, $ b = 2 nunca será evaluado!

3

Ver: http://php.net/manual/en/language.variables.scope.php

entre llaves php no definen necesariamente un nuevo ámbito para las variables. (su primer ejemplo)

En su segundo ejemplo, $ b solo está configurado en una condición específica. Por lo tanto, es posible estar "indefinido" si no se cumple esta condición.

+0

¡Gracias por el enlace y su respuesta! – Shyam

1

En realidad, su primer método también debería darle un error.

Estás usando una variable que no ha sido declarado como una matriz. No puedo entender por qué no obtuviste un error por eso.

PHP no tiene ámbito de bloque, por lo que si está dentro de IF o FOREACH es irrelevante. Si está disponible dentro del método, puede usarlo dentro del método.

Cuestiones relacionadas