De los isset()
documentos :
isset() will return FALSE if testing a variable that has been set to NULL.
Básicamente, isset()
no verifica si la variable está configurada en absoluto, sino si está configurada en algo diferente NULL
.
Dado eso, ¿cuál es la mejor manera de verificar la existencia de una variable? Intenté algo como:
if(isset($v) || @is_null($v))
( @
es necesario para evitar la advertencia cuando $v
no está configurado) pero is_null()
tiene un problema similar al siguiente isset()
: ¡regresa TRUE
en variables no configuradas! También parece que:
@($v === NULL)
funciona exactamente como @is_null($v)
, así que eso también está fuera.
¿Cómo se supone que debemos verificar de manera confiable la existencia de una variable en PHP?
Editar: hay claramente una diferencia en PHP entre las variables que no están configuradas y las variables que están configuradas en NULL
:
<?php
$a = array('b' => NULL);
var_dump($a);
PHP muestra que $a['b']
existe y tiene un NULL
valor. Si agrega:
var_dump(isset($a['b']));
var_dump(isset($a['c']));
Puedes ver la ambigüedad de la que estoy hablando con la isset()
función. Aquí está el resultado de los tres var_dump()s
:
array(1) {
["b"]=>
NULL
}
bool(false)
bool(false)
Edición adicional: dos cosas.
Uno, un caso de uso. Una matriz que se convierte en los datos de una UPDATE
instrucción SQL , donde las claves de la matriz son las columnas de la tabla, y los valores de la matriz son los valores que se aplicarán a cada columna. Cualquiera de las columnas de la tabla puede contener un NULL
valor, significando pasando un NULL
valor en la matriz. Usted necesita una manera de diferenciar entre una clave matriz no existente, y el valor de un array se configura a NULL
; esa es la diferencia entre no actualizar el valor de la columna y actualizar el valor de la columna a NULL
.
En segundo lugar, la respuesta de Zoredache , array_key_exists()
funciona correctamente, para mi caso de uso por encima y por ninguna variable global:
<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));
salidas:
bool(true)
bool(false)
Dado que eso se maneja correctamente en casi todas partes, puedo ver que existe alguna ambigüedad entre las variables que no existen y las variables configuradas NULL
, estoy llamando a array_key_exists()
la forma oficial más fácil en PHP para verificar realmente la existencia de una variable .
(Solo otro caso en el que puedo pensar es para las propiedades de clase, para las cuales hay property_exists()
, que, según sus documentos , funciona de manera similar, ya array_key_exists()
que distingue adecuadamente entre no establecerse y establecerse en NULL
).
register_globals
, todavía me cuesta pensar en una situación en la que incluso eso requeriría tal distinción, ya que cualquier cosa registrada desde la solicitud HTTP siempre sería una cadena, nonull
.Respuestas:
Si la variable que está verificando estaría en el ámbito global que podría hacer:
fuente
$defined_vars = get_defined_vars();
y luego probar a través dearray_key_exists('v', $defined_vars);
.isset($foo[$bar])
se convierte enarray_key_exists($bar, $foo)
property_exists
parece prometedor, excepto por esto:> La función property_exists () no puede detectar propiedades que sean mágicamente accesibles usando el método mágico __get.Intentando dar una visión general de las diversas discusiones y respuestas:
No hay una respuesta única a la pregunta que pueda reemplazar todas las formas en que
isset
se puede utilizar. Algunos casos de uso son abordados por otras funciones, mientras que otros no resisten el escrutinio o tienen un valor dudoso más allá del código golf. Lejos de estar "roto" o "inconsistente", otros casos de uso demuestran por quéisset
la reacción a estanull
es la conducta lógica.Casos de uso real (con soluciones)
1. Teclas de matriz
Las matrices pueden tratarse como colecciones de variables,
unset
yisset
tratarlas como si lo fueran. Sin embargo, dado que pueden iterarse, contarse, etc., un valor faltante no es lo mismo que uno cuyo valor esnull
.La respuesta en este caso, es usar en
array_key_exists()
lugar deisset()
.Como esto toma la matriz para verificar como argumento de función, PHP aún generará "avisos" si la matriz en sí misma no existe. En algunos casos, se puede argumentar válidamente que cada dimensión debería haberse inicializado primero, por lo que el aviso está haciendo su trabajo. Para otros casos, una función "recursiva"
array_key_exists
, que verificaba cada dimensión de la matriz a su vez, evitaría esto, pero básicamente sería lo mismo que@array_key_exists
. También es algo tangencial al manejo denull
valores.2. Propiedades del objeto
En la teoría tradicional de la "Programación orientada a objetos", la encapsulación y el polimorfismo son propiedades clave de los objetos; en una aplicación orientada a objetos basado en clases como PHP de las propiedades encapsulados se declaran como parte de la definición de clase, y dados los niveles de acceso (
public
,protected
oprivate
).Sin embargo, PHP también le permite agregar dinámicamente propiedades a un objeto, como lo haría con las claves de una matriz, y algunas personas usan objetos sin clase (técnicamente, instancias de lo incorporado
stdClass
, que no tiene métodos o funcionalidad privada) camino a matrices asociativas. Esto lleva a situaciones en las que una función puede querer saber si se ha agregado una propiedad particular al objeto que se le ha asignado.Al igual que con claves de matriz, una solución para el control de las propiedades del objeto se incluye en el lenguaje, llamado, razonablemente,
property_exists
.Casos de uso no justificables, con discusión
3.
register_globals
, y otra contaminación del espacio de nombres globalLa
register_globals
característica agregó variables al ámbito global cuyos nombres fueron determinados por aspectos de la solicitud HTTP (parámetros GET y POST y cookies). Esto puede conducir a códigos con errores e inseguros, por lo que se ha deshabilitado de forma predeterminada desde PHP 4.2, lanzado en agosto de 2000 y eliminado por completo en PHP 5.4, lanzado en marzo de 2012 . Sin embargo, es posible que algunos sistemas todavía se estén ejecutando con esta función habilitada o emulada. También es posible "contaminar" el espacio de nombres global de otras maneras, utilizando laglobal
palabra clave o$GLOBALS
matriz.En primer lugar,
register_globals
es poco probable que produzca unanull
variable inesperadamente , ya que los valores GET, POST y cookie siempre serán cadenas (con''
todavía regresandotrue
deisset
), y las variables en la sesión deben estar completamente bajo el control del programador.En segundo lugar, la contaminación de una variable con el valor
null
es solo un problema si esto sobrescribe alguna inicialización previa. "Sobreescribir" una variable no inicializadanull
solo sería problemático si el código en otro lugar distinguiera entre los dos estados, por lo que esta posibilidad es un argumento en contra de hacer tal distinción.4.
get_defined_vars
ycompact
Algunas funciones raramente utilizadas en PHP, como
get_defined_vars
ycompact
, le permiten tratar los nombres de variables como si fueran claves en una matriz. Para las variables globales, la matriz superglobal$GLOBALS
permite un acceso similar y es más común. Estos métodos de acceso se comportarán de manera diferente si una variable no está definida en el alcance relevante.Una vez que haya decidido tratar un conjunto de variables como una matriz utilizando uno de estos mecanismos, puede realizar las mismas operaciones en él que en cualquier matriz normal. En consecuencia, ver 1.
La funcionalidad que existía solo para predecir cómo estas funciones están a punto de comportarse (por ejemplo, "¿habrá una clave 'foo' en la matriz devuelta por
get_defined_vars
?") Es superflua, ya que simplemente puede ejecutar la función y descubrir sin efectos nocivos.4a. Variables variables (
$$foo
)Aunque no es lo mismo que las funciones que convierten un conjunto de variables en una matriz asociativa, la mayoría de los casos que usan "variables variables" ("asignar a una variable nombrada en base a esta otra variable") pueden y deben cambiarse para usar una matriz asociativa. .
Un nombre de variable, fundamentalmente, es la etiqueta dada a un valor por el programador; si lo está determinando en tiempo de ejecución, no es realmente una etiqueta sino una clave en algún almacén de valores clave. Más prácticamente, al no usar una matriz, está perdiendo la capacidad de contar, iterar, etc. También puede ser imposible tener una variable "fuera" del almacén de valores clave, ya que podría sobrescribirse
$$foo
.Una vez que se cambia para usar una matriz asociativa, el código será apto para la solución 1. El acceso indirecto a la propiedad del objeto (por ejemplo
$foo->$property_name
) se puede abordar con la solución 2.5.
isset
es mucho más fácil de escribir quearray_key_exists
No estoy seguro de que esto sea realmente relevante, pero sí, los nombres de funciones de PHP pueden ser bastante largos e inconsistentes a veces. Aparentemente, las versiones prehistóricas de PHP usaban la longitud del nombre de una función como una clave hash, por lo que Rasmus inventaba deliberadamente nombres de funciones como
htmlspecialchars
para que tuvieran una cantidad inusual de caracteres ...Aún así, al menos no estamos escribiendo Java, ¿eh? ;)
6. Las variables no inicializadas tienen un tipo
La página del manual sobre conceptos básicos variables incluye esta declaración:
No estoy seguro de si hay alguna noción en el motor Zend de "tipo no inicializado pero conocido" o si esto está leyendo demasiado en la declaración.
Lo que está claro es que no hace una diferencia práctica en su comportamiento, ya que los comportamientos descritos en esa página para las variables no inicializadas son idénticos al comportamiento de una variable cuyo valor es
null
. Para elegir un ejemplo, ambos$a
y$b
en este código terminarán como el entero42
:(El primero generará un aviso sobre una variable no declarada, en un intento de hacer que escriba un código mejor, pero no hará ninguna diferencia en cómo se ejecuta el código).
99. Detectar si una función se ha ejecutado
(Mantener este último, ya que es mucho más largo que los demás. Tal vez lo edite más tarde ...)
Considere el siguiente código:
Si
some_function
puede regresarnull
, existe la posibilidad de queecho
no se llegue a él aunque se hayasome_test
devueltotrue
. La intención del programador era detectar cuándo$result
nunca se había configurado, pero PHP no les permite hacerlo.Sin embargo, hay otros problemas con este enfoque, que se vuelven claros si agrega un bucle externo:
Debido a
$result
que nunca se inicializa explícitamente, tomará un valor cuando pase la primera prueba, lo que hace imposible saber si las pruebas posteriores pasaron o no. Esto es realmente un error extremadamente común cuando las variables no se inicializan correctamente.Para solucionar esto, necesitamos hacer algo en la línea donde he comentado que falta algo. La solución más obvia es establecer
$result
un "valor terminal" quesome_function
nunca pueda regresar; Si es asínull
, el resto del código funcionará bien. Si no hay un candidato natural para un valor terminal porquesome_function
tiene un tipo de retorno extremadamente impredecible (que probablemente sea un mal signo en sí mismo), entonces$found
podría usarse un valor booleano adicional, por ejemplo , en su lugar.Pensamiento experimento uno: la
very_null
constantePHP teóricamente podría proporcionar una constante especial, así como también
null
, para usar aquí como valor terminal; presumiblemente, sería ilegal devolver esto desde una función, o sería forzado a hacerlonull
, y lo mismo probablemente se aplicaría al pasarlo como un argumento de función. Eso haría que este caso muy específico fuera un poco más simple, pero tan pronto como decidiera volver a factorizar el código, por ejemplo, para poner el bucle interno en una función separada, se volvería inútil. Si la constante se pudiera pasar entre funciones, no podría garantizar quesome_function
no la devolvería, por lo que ya no sería útil como valor de terminal universal.El argumento para detectar variables no inicializadas en este caso se reduce al argumento de esa constante especial: si reemplaza el comentario
unset($result)
y lo trata de manera diferente$result = null
, está introduciendo un "valor" para$result
que no se pueda pasar, y solo puede ser detectado por funciones incorporadas específicas.Pensamiento experimento dos: contador de asignación
Otra forma de pensar acerca de lo que el último
if
pregunta es "algo ha hecho una asignación a$result
?" En lugar de considerarlo como un valor especial de$result
, tal vez podría pensar en esto como "metadatos" sobre la variable, un poco como la "contaminación variable" de Perl. Así que en lugar deisset
que podría llamarhas_been_assigned_to
, y en lugar deunset
,reset_assignment_state
.Pero si es así, ¿por qué detenerse en un booleano? ¿Qué sucede si desea saber cuántas veces pasó la prueba? simplemente podría extender sus metadatos a un número entero y tener
get_assignment_count
yreset_assignment_count
...Obviamente, agregar tal característica tendría una compensación en la complejidad y el rendimiento del lenguaje, por lo que debería sopesarse cuidadosamente en función de su utilidad esperada. Al igual que con una
very_null
constante, sería útil solo en circunstancias muy estrechas y sería igualmente resistente a la refactorización.La pregunta con suerte obvia es por qué el motor de tiempo de ejecución de PHP debería asumir de antemano que desea realizar un seguimiento de tales cosas, en lugar de dejar que lo haga explícitamente, utilizando un código normal.
fuente
A veces me pierdo un poco tratando de averiguar qué operación de comparación usar en una situación dada.
isset()
solo se aplica a valores no inicializados o explícitamente nulos. Pasar / asignar nulo es una excelente manera de garantizar que una comparación lógica funcione como se esperaba.Aún así, es un poco difícil de pensar, así que aquí hay una matriz simple que compara cómo diferentes valores serán evaluados por diferentes operaciones:
Para ajustar la tabla comprimí un poco las etiquetas:
$a;
se refiere a una variable declarada pero no asignada$a = null;
$a = [];
$a = 0;
$a === null
isset($a)
empty($a)
$a ? true : false
Todos los resultados son booleanos,
true
se imprimen yfalse
se omiten.Puede ejecutar las pruebas usted mismo, verifique esta esencia:
https://gist.github.com/mfdj/8165967
fuente
"0"
a la tabla, para completar y aclarar laempty
operaciónPuede usar la construcción de lenguaje compacto para probar la existencia de una variable nula. Las variables que no existen no aparecerán en el resultado, mientras que se mostrarán valores nulos.
En el caso de tu ejemplo:
Por supuesto, para las variables de alcance global también puede usar array_key_exists ().
Por cierto, personalmente evitaría situaciones como la peste donde hay una diferencia semántica entre una variable que no existe y la variable que tiene un valor nulo. PHP y la mayoría de los otros lenguajes simplemente no creen que exista.
fuente
NULL
. Semánticamente,NULL
debería significar "sin recurso", pero no definir una variable es un error del programador.undefined
ynull
son tan raras que no me lo pierdo. En mi humilde opinión, el uso principalundefined
es "error de programador en un lenguaje no estricto". En un lenguaje estricto, si necesito un estado distinto paraclient did not state a value
, entonces declaro un valor apropiado para la situación y lo pruebo. En el peor de los casos, tiene que agregar una variable de bandera separada. ¡Pero hacer eso rara vez es mejor que SIEMPRE hacer frente a DOS estados diferentes sin valor!Explicando NULL, lógicamente pensando
Supongo que la respuesta obvia a todo esto es ... No inicialice sus variables como NULL, inicialícelas como algo relevante para lo que están destinadas a convertirse.
Tratar NULL adecuadamente
NULL debe tratarse como "valor no existente", que es el significado de NULL. La variable no puede clasificarse como existente en PHP porque no se le ha dicho qué tipo de entidad está tratando de ser. Es posible que tampoco exista, por lo que PHP simplemente dice "Bien, no lo hace porque de todos modos no tiene sentido y NULL es mi forma de decir esto".
Un argumento
Discutamos ahora. "Pero NULL es como decir 0 o FALSE o ''.
Incorrecto, 0-FALSO- '' todavía se clasifican como valores vacíos, pero se especifican como algún tipo de valor o respuesta predeterminada a una pregunta. FALSO es la respuesta a sí o no '', es la respuesta al título que alguien envió, y 0 es la respuesta a la cantidad o el tiempo, etc. ESTÁN configurados como algún tipo de respuesta / resultado que los hace válidos como establecidos.
NULL simplemente no tiene respuesta, no nos dice sí o no y no nos dice la hora y no nos dice que se envió una cadena en blanco. Esa es la lógica básica para entender NULL.
Resumen
No se trata de crear funciones extrañas para solucionar el problema, solo está cambiando la forma en que su cerebro ve NULL. Si es NULL, suponga que no está configurado como nada. Si está predefiniendo variables, defínelas como 0, FALSO o "" dependiendo del tipo de uso que desee para ellas.
Siéntase libre de citar esto. Está fuera de la parte superior de mi cabeza lógica :)
fuente
isset($a['x'])
le dirá falso six
es nulo, pero aparecerá encount($a)
...compact
funcionará en todas las variables establecidas, incluidasnulls
, etc.Property_exists puede verificar la existencia de las propiedades de los objetos
Ejemplo de una prueba unitaria:
fuente
Como una adición a la discusión de greatbigmassive sobre lo que significa NULL , considere lo que realmente significa "la existencia de una variable".
En muchos idiomas, debe declarar explícitamente cada variable antes de usarla ; esto puede determinar su tipo, pero lo más importante es que declara su alcance . Una variable "existe" en todas partes en su alcance, y en ninguna parte fuera de ella, ya sea una función completa o un solo "bloque".
Dentro de su alcance, una variable asigna algún significado a una etiqueta que usted, el programador, ha elegido. Fuera de su alcance, esa etiqueta no tiene sentido (si usa la misma etiqueta en un alcance diferente es básicamente irrelevante).
En PHP, no es necesario declarar las variables : cobran vida tan pronto como las necesite. Cuando escribe en una variable por primera vez, PHP asigna una entrada en memoria para esa variable. Si lee de una variable que actualmente no tiene una entrada, PHP considera que esa variable tiene el valor
NULL
.Sin embargo, los detectores automáticos de calidad de código generalmente le avisarán si usa una variable sin "inicializarla" primero. En primer lugar, esto ayuda a detectar errores tipográficos, como asignar a,
$thingId
pero leer desde$thing_id
; pero en segundo lugar, te obliga a considerar el alcance sobre el cual esa variable tiene significado, tal como lo haría una declaración.Cualquier código que se preocupe si una variable "existe" es parte del alcance de esa variable , ya sea que se haya inicializado o no, usted como programador le ha dado a esa etiqueta el significado en ese punto del código. Como lo está utilizando, en cierto sentido debe "existir", y si existe, debe tener un valor implícito; en PHP, ese valor implícito es
null
.Debido a la forma en que funciona PHP, es posible escribir código que trate el espacio de nombres de las variables existentes no como un alcance de etiquetas a las que le ha dado significado, sino como algún tipo de almacén de valores clave. Puede, por ejemplo, ejecutar código de la siguiente manera:
$var = $_GET['var_name']; $$var = $_GET['var_value'];
. Solo porque puedas, no significa que sea una buena idea.Resulta que PHP tiene una forma mucho mejor de representar las tiendas de valores clave, llamadas matrices asociativas. Y aunque los valores de una matriz se pueden tratar como variables, también puede realizar operaciones en la matriz como un todo. Si tiene una matriz asociativa, puede probar si contiene una clave usando
array_key_exists()
.También puede usar objetos de manera similar, estableciendo dinámicamente propiedades, en cuyo caso puede usar
property_exists()
exactamente de la misma manera. Por supuesto, si se define una clase, se puede declarar qué propiedades se ha - incluso se puede elegir entrepublic
,private
yprotected
ámbito de aplicación.Aunque existe una diferencia técnica entre una variable (en oposición a una clave de matriz o una propiedad de objeto) que no se ha inicializado (o que se ha explícitamente
unset()
) y una cuyo valor esnull
, cualquier código que considere que esa diferencia es significativa está utilizando variables de una manera que no están destinadas a ser utilizadas.fuente
isset()
comporta de esa manera?".null
. Si ese valor existe antes de mirarlo es una cuestión para los filósofos, pero en lo que respecta a cualquier comportamiento observable, el valor es consistentenull
.isset
comprueba si la variable está establecida y, si es así, si su valor no es NULL. La última parte (en mi opinión) no está dentro del alcance de esta función. No existe una solución alternativa decente para determinar si una variable es NULL porque no está establecida o porque está establecida explícitamente en NULL .Aquí hay una posible solución:
Otra solución es probar la salida de
get_defined_vars()
:fuente
No estoy de acuerdo con su razonamiento sobre NULL , y decir que necesita cambiar su mentalidad sobre NULL es simplemente extraño.
Creo que isset () no se diseñó correctamente, isset () debería decirle si la variable se ha establecido y no debería preocuparse por el valor real de la variable.
¿Qué sucede si está comprobando los valores devueltos por una base de datos y una de las columnas tiene un valor NULL? Todavía desea saber si existe incluso si el valor es NULL ... no, no confíe en isset () aquí.
igualmente
isset () debería haber sido diseñado para funcionar así:
de esta manera, dejamos que el programador verifique los tipos y no lo dejemos en isset () para asumir que no está allí porque el valor es NULL, es simplemente un diseño estúpido
fuente
array_key_exists
. Nunca debe encontrarse en una situación en la que no sabe en tiempo de ejecución si existe una variable real.register_globals
, entonces su respuesta no es un cambio aisset()
. El manual de PHP menciona que "generalmente es una buena práctica de programación inicializar variables primero", lo que resuelveregister_globals
en tiempo de diseño en lugar de en tiempo de ejecución. También hay una entrada de preguntas frecuentes que ofrece unaunregister_globals()
función para tratarla en tiempo de ejecución.Voy a agregar dos centavos rápidos a esto. Una razón por la cual este problema es confuso es porque este escenario parece devolver el mismo resultado con un informe de error no completo:
Podría suponer a partir de este resultado que la diferencia entre
$a = null
y no definir$b
nada es nada.Error de arranque informando:
Nota: arrojó un error variable indefinido, pero el valor de salida de
var_dump
todavíaNULL
.PHP obviamente tiene una capacidad interna para distinguir entre una variable nula y una variable indefinida. Me parece que debería haber una función integrada para verificar esto.
Creo que la respuesta aceptada es buena en su mayor parte, pero si fuera a implementarla, escribiría un contenedor para ella. Como se mencionó anteriormente en esta respuesta , tengo que aceptar que en realidad no he encontrado una situación en la que esto haya sido un problema. Parece que casi siempre termino en un escenario donde mis variables están establecidas y definidas, o no lo están (indefinidas, sin definir, nulas, en blanco, etc.). No quiere decir que una situación como esta no ocurra en el futuro, pero como parece ser un problema único, no me sorprende que los desarrolladores de PHP no se hayan molestado en poner esto.
fuente
Si ejecuto lo siguiente:
Me sale un error:
Si ejecuto lo siguiente:
No recibo el error.
Si tengo una variable que debería establecerse, generalmente hago algo como lo siguiente.
o
De esa manera, más adelante en el script, puedo usar $ foo de manera segura y saber que "está configurado" y que por defecto es nulo. Luego puedo
if ( is_null($foo) ) { /* ... */ }
si lo necesito y sé con certeza que la variable existe, incluso si es nula.La documentación completa de isset lee un poco más de lo que se pegó inicialmente. Sí, devuelve falso para una variable que se estableció anteriormente pero ahora es nula, pero también devuelve falso si una variable aún no se ha establecido (alguna vez) y para cualquier variable que se haya marcado como no establecida. También observa que el byte NULL ("\ 0") no se considera nulo y devolverá verdadero.
fuente
Intenta usar
Parece que la única vez que no se establece una variable es cuando se desarma específicamente ($ v). Parece que su significado de 'existencia' es diferente a la definición de PHP. NULL ciertamente existe, es NULL.
fuente
Tengo que decir que en todos mis años de programación PHP, nunca me he encontrado con un problema al
isset()
devolver false en una variable nula. OTOH, he encontrado problemas alisset()
fallar en una entrada de matriz nula, peroarray_key_exists()
funciona correctamente en ese caso.Para alguna comparación, Icon define explícitamente una variable no utilizada como retorno,
&null
por lo que utiliza la prueba nula en Icon para verificar también una variable no establecida. Esto hace las cosas más fáciles. Por otro lado, Visual BASIC tiene múltiples estados para una variable que no tiene un valor (Nulo, Vacío, Nada, ...), y a menudo tiene que verificar más de uno de ellos. Esto se sabe que es una fuente de errores.fuente
De acuerdo con el Manual de PHP para la función empty (), "Determine si una variable se considera vacía. Una variable se considera vacía SI NO EXISTE o si su valor es FALSO. Empty () no genera una advertencia si el la variable no existe ". (Mi énfasis.) Eso significa que la función empty () debería calificar como "la mejor manera de probar la existencia de una variable en PHP", según el título Pregunta.
Sin embargo, esto no es lo suficientemente bueno, porque la función empty () puede ser engañada por una variable que sí existe y está establecida en NULL.
Estoy interrumpiendo mi respuesta anterior para presentar algo mejor, porque es menos engorroso que mi respuesta original (que sigue a esta interrupción, para comparar).
Dos líneas simples de código pueden usar la función anterior para revelar si una variable no está definida:
Puede seguir esas dos líneas con cualquier cosa apropiada, como este ejemplo:
Quería poner la llamada a ob_start () y el ($ testvar === null) dentro de la función, y simplemente pasar la variable a la función, pero no funciona. Incluso si intenta utilizar "pasar por referencia" de la variable a la función, la variable SE CONVIERTE en definida, y luego la función nunca puede detectar que previamente no había sido definida. Lo que se presenta aquí es un compromiso entre lo que quería hacer y lo que realmente funciona.
Lo anterior implica que hay otra forma de evitar siempre encontrarse con el mensaje de error "Variable indefinida". (La suposición aquí es que la prevención de dicho mensaje es la razón por la que desea probar para ver si una variable no está definida).
Simplemente llame a esa función antes de hacer algo a su $ testvar:
¡El valor de la variable recién instanciada se establece en nulo, por supuesto!
(Finaliza la interrupción)
Entonces, después de estudiar y experimentar, aquí hay algo que funciona:
La explicación: una variable $ er se inicializa a un valor predeterminado de "sin error". Se define una "función de controlador". Si $ testvar (la variable que queremos saber si no está definida o no) pasa la prueba preliminar de función empty (), entonces hacemos la prueba más exhaustiva. Llamamos a la función set_error_handler () para usar la función de controlador previamente definida. Luego hacemos una comparación de identidad simple que involucra $ testvar, QUE SI NO ESTÁ DEFINIDO, ACTIVARÁ UN ERROR. La función de controlador captura el error y prueba específicamente para ver si la razón del error es el hecho de que la variable no está definida. El resultado se coloca en la variable de información de error $ er, que luego podemos probar para hacer lo que queramos como resultado de saber con seguridad si $ testvar se definió o no. Debido a que solo necesitamos la función de controlador para este propósito limitado, restauramos la función original de manejo de errores. La función "myHndlr" solo necesita declararse una vez; el otro código se puede copiar en cualquier lugar que sea apropiado, para $ testvar o cualquier otra variable que queramos probar de esta manera.
fuente
inst
función es básicamente como el@
operador de supresión de errores: "Sé que estoy haciendo algo mal aquí, pero solo quiero que ese mensaje desaparezca, sin cambiar realmente el funcionamiento de mi código de ninguna manera".Creo que la única solución completa es informar avisos con
Pero tendrá que corregir todos los avisos generados por variables indefinidas, constantes, claves de matriz, propiedades de clase, entre otros. Una vez que haya hecho eso, no tendrá que preocuparse por la diferencia entre variables nulas y no declaradas, y la ambigüedad desaparece.
Habilitación de informes de notificación puede no ser una buena alternativa en todas las situaciones, pero existen buenas razones para hacerlo:
¿Por qué debería corregir los errores de E_NOTICE?
En mi caso, llevaba más de un año trabajando en un proyecto sin él, pero solía tener cuidado al declarar variables, por lo que la transición fue rápida.
fuente
La única forma de saber si una variable está definida en el alcance actual (
$GLOBALS
no es confiable) esarray_key_exists( 'var_name', get_defined_vars() )
.fuente
Prefiero usar no vacío como el mejor método para verificar la existencia de una variable que a) existe yb) no es nula.
fuente
empty()
no comprueba si la variable es nulo, se comprueba si es falso-y, por ejemplo, no una de la""
(una cadena vacía),0
(0 como un entero),0.0
(0 como un flotador),"0"
(0 como una cadena),NULL
,FALSE
,array()
(una matriz vacía) y$var;
(una variable declarada, pero sin un valor). Digamos que tiene un campo de radio requerido en un formulario con dos entradas con los valores0
y1
. Si lo usaempty()
para la validación y el usuario selecciona el que está usando0
, accidentalmente se equivocará "el campo requerido no puede estar vacío". Consulte el manual php.net/manual/en/function.empty.php