Nota: Esta es una pregunta de referencia para tratar con alcance variable en PHP. Cierre cualquiera de las muchas preguntas que se ajustan a este patrón como un duplicado de este.
¿Qué es el "alcance variable" en PHP? ¿Son accesibles las variables de un archivo .php en otro? ¿Por qué a veces obtengo errores de "variable indefinida" ?
Respuestas:
¿Qué es el "alcance variable"?
Las variables tienen un "alcance" o "lugares desde los cuales son accesibles". El hecho de que haya escrito
$foo = 'bar';
una vez en algún lugar de su aplicación no significa que pueda hacer referencia$foo
desde cualquier otro lugar dentro de la aplicación. La variable$foo
tiene un cierto alcance dentro del cual es válida y solo el código del mismo alcance tiene acceso a la variable.¿Cómo se define un alcance en PHP?
Muy simple: PHP tiene alcance de función . Ese es el único tipo de separador de alcance que existe en PHP. Las variables dentro de una función solo están disponibles dentro de esa función. Las variables fuera de las funciones están disponibles en cualquier lugar fuera de las funciones, pero no dentro de ninguna función. Esto significa que hay un alcance especial en PHP: el alcance global . Cualquier variable declarada fuera de cualquier función está dentro de este alcance global.
Ejemplo:
$foo
está en el ámbito global ,$baz
está en un ámbito local dentromyFunc
. Solo el código internomyFunc
tiene acceso a$baz
. Solo el código externomyFunc
tiene acceso a$foo
. Ninguno tiene acceso al otro:Alcance y archivos incluidos
Los límites del archivo no separan el alcance:
a.php
b.php
Se aplican las mismas reglas al
include
código d que a cualquier otro código: solofunction
el alcance separado. Para fines de alcance, puede pensar en incluir archivos como copiar y pegar código:c.php
En el ejemplo anterior,
a.php
se incluyó dentromyFunc
, cualquier variable dentroa.php
solo tiene un alcance de función local. El hecho de que parezcan estar en el ámbito globala.php
no significa necesariamente que lo estén, sino que depende del contexto en el que se incluye / ejecuta ese código.¿Qué pasa con las funciones dentro de las funciones y clases?
Cada nueva
function
declaración introduce un nuevo alcance, es así de simple.(anónimo) funciones dentro de funciones
clases
¿Para qué sirve el alcance?
Tratar los problemas de alcance puede parecer molesto, ¡pero el alcance variable limitado es esencial para escribir aplicaciones complejas! Si cada variable que declara estaría disponible desde cualquier otro lugar dentro de su aplicación, estaría pasando por encima de sus variables sin una forma real de rastrear qué cambia qué. Hay pocos nombres razonables que puede dar a sus variables, probablemente quiera usar la variable "
$name
" en más de un lugar. Si solo pudiera tener este nombre de variable único una vez en su aplicación, tendría que recurrir a esquemas de nombres realmente complicados para asegurarse de que sus variables sean únicas y que no esté cambiando la variable incorrecta del código incorrecto.Observar:
Si no hubiera alcance, ¿qué haría la función anterior? De donde
$bar
viene ¿Qué estado tiene? ¿Es incluso inicializado? ¿Tienes que revisar cada vez? Esto no es mantenible. Lo que nos lleva a ...Cruzando los límites del alcance
La forma correcta: pasar variables dentro y fuera
La variable
$bar
entra explícitamente en este ámbito como argumento de función. Con solo mirar esta función, queda claro de dónde provienen los valores con los que trabaja. Luego, devuelve explícitamente un valor. La persona que llama tiene la confianza de saber con qué variables trabajará la función y de dónde provienen sus valores de retorno:Extender el alcance de las variables a funciones anónimas.
La función anónima incluye explícitamente
$foo
desde su alcance circundante. Tenga en cuenta que esto no es lo mismo que el alcance global .La forma incorrecta:
global
Como se dijo antes, el alcance global es algo especial, y las funciones pueden importar explícitamente variables de él:
Esta función usa y modifica la variable global
$foo
. ¡No hagas esto! (A menos que realmente realmente realmente sepas lo que estás haciendo, e incluso entonces: ¡no!)Todo lo que ve la persona que llama de esta función es esto:
No hay indicios de que esta función tenga efectos secundarios , pero sí. Esto se convierte fácilmente en un lío enredado ya que algunas funciones se siguen modificando y requieren un estado global. Desea que las funciones no tengan estado , que actúen solo en sus entradas y que devuelvan salidas definidas, por muchas veces que las llame.
Debe evitar utilizar el alcance global de la forma más amplia posible; sin duda no debería "sacar" las variables del ámbito global a un ámbito local.
fuente
global
, así que díganos cuándo debemos usarloglobal
. Y por favor explique (un poco) ¿qué esstatic
...?global
. Siempre esta mal. Pasar los parámetros de la función es correcto.static
se explica bien en el manual y no tiene mucho que ver con el alcance. En pocas palabras, puede considerarse como una "variable global con ámbito". Estoy ampliando un poco su uso aquí kunststube.net/static .include_once
y posiblementerequire_once
también debería agregarse en alguna parte; solo digo. OP votó para reabrir su pregunta también. ¿Sería su publicación un caso especial y qué se debe hacer al respecto?Aunque no se puede acceder a las variables definidas dentro del alcance de una función desde el exterior, eso no significa que no pueda usar sus valores después de que esa función se complete. PHP tiene una
static
palabra clave bien conocida que se usa ampliamente en PHP orientado a objetos para definir métodos y propiedades estáticos, pero se debe tener en cuenta questatic
también se puede usar dentro de las funciones para definir variables estáticas.¿Qué es 'variable estática'?
La variable estática difiere de la variable ordinaria definida en el alcance de la función en caso de que no pierda valor cuando la ejecución del programa abandona este alcance. Consideremos el siguiente ejemplo de uso de variables estáticas:
Resultado:
Si hubiéramos definido
$counter
sin élstatic
, cada valor de eco sería el mismo que el$num
parámetro pasado a la función. El usostatic
permite crear este contador simple sin una solución adicional.Casos de uso de variables estáticas
Trucos
La variable estática solo existe en un ámbito de función local. No se puede acceder fuera de la función en la que se ha definido. Por lo tanto, puede estar seguro de que mantendrá su valor sin cambios hasta la próxima llamada a esa función.
La variable estática solo se puede definir como una expresión escalar o escalar (desde PHP 5.6). Asignarle otros valores inevitablemente conduce a un fracaso al menos en el momento en que se escribió este artículo. Sin embargo, puede hacerlo solo en la siguiente línea de su código:
Resultado:
La función estática es un poco 'compartida' entre métodos de objetos de la misma clase. Es fácil de entender al ver el siguiente ejemplo:
Esto solo funciona con objetos de la misma clase. Si los objetos son de diferentes clases (incluso extendiéndose entre sí), el comportamiento de los vars estáticos será el esperado.
¿Es la variable estática la única forma de mantener valores entre llamadas a una función?
Otra forma de mantener valores entre las llamadas a funciones es usar cierres. Los cierres se introdujeron en PHP 5.3. En dos palabras, le permiten limitar el acceso a un conjunto de variables dentro del alcance de una función a otra función anónima que será la única forma de acceder a ellas. Estar en variables de cierre puede imitar (más o menos exitosamente) conceptos de OOP como 'constantes de clase' (si se aprobaron en cierre por valor) o 'propiedades privadas' (si se pasan por referencia) en programación estructurada.
Este último realmente permite usar cierres en lugar de variables estáticas. El desarrollador siempre debe decidir qué usar, pero debe mencionarse que las variables estáticas son definitivamente útiles cuando se trabaja con recursiones y merecen ser notadas por los desarrolladores.
fuente
No publicaré una respuesta completa a la pregunta, ya que las existentes y el manual de PHP hacen un gran trabajo al explicar la mayor parte de esto.
Sin embargo, un tema que se perdió fue la de superglobales , incluyendo el uso común
$_POST
,$_GET
,$_SESSION
, etc. Estas variables son matrices que están siempre disponibles, en cualquier ámbito, sin unaglobal
declaración.Por ejemplo, esta función imprimirá el nombre del usuario que ejecuta el script PHP. La variable está disponible para la función sin ningún problema.
La regla general de "los globales son malos" generalmente se modifica en PHP a "los globales son malos pero los superglobales están bien", siempre y cuando uno no los esté usando mal. (Todas estas variables son grabables, por lo que podrían usarse para evitar la inyección de dependencia si fuera realmente terrible).
No se garantiza que estas variables estén presentes; un administrador puede deshabilitar todos o algunos de ellos usando la
variables_order
directiva enphp.ini
, pero esto no es un comportamiento común.Una lista de superglobales actuales:
$GLOBALS
- Todas las variables globales en el script actual$_SERVER
- Información sobre el servidor y el entorno de ejecución.$_GET
- Valores pasados en la cadena de consulta de la URL, independientemente del método HTTP utilizado para la solicitud$_POST
- Valores pasados en una solicitud HTTP POST con tipos MIMEapplication/x-www-form-urlencoded
omultipart/form-data
$_FILES
- Archivos pasados en una solicitud HTTP POST con unmultipart/form-data
tipo MIME$_COOKIE
- Cookies pasadas con la solicitud actual$_SESSION
- Variables de sesión almacenadas internamente por PHP$_REQUEST
- Típicamente una combinación de$_GET
y$_POST
, pero a veces$_COOKIES
. El contenido está determinado por larequest_order
directiva enphp.ini
.$_ENV
- Las variables de entorno del script actualfuente