Nulo vs. Falso vs. 0 en PHP

146

Me dicen que los buenos desarrolladores pueden detectar / utilizar la diferencia entre Nully Falsey 0y todas las demás entidades buenas "nada".
¿Cuál es la diferencia, específicamente en PHP? ¿Tiene algo que ver con ===?

Stalepretzel
fuente
Es casi imposible realmente saber cuándo se usa. Supongo que es importante que seas CONSISTENTE cuando lo usas nully cuándo false. Yo prefiero usar nullal recuperar un valor de un método, porque puedo usar issetpara determinar si un valor es devuelto en lugar de utilizar emptyque no tendrá en cuenta: false, 0, '0'o una cadena vacía, que pueden ser valores viables en muchas situaciones. Para mí es la solución más limpia en una construcción desordenada.
JMRC

Respuestas:

221

Es específico del lenguaje, pero en PHP:

Nullsignifica " nada ". La var no se ha inicializado.

Falsesignifica " no es cierto en un contexto booleano ". Se usa para mostrar explícitamente que se trata de problemas lógicos.

0 es un int . Nada que ver con el resto anterior, utilizado para las matemáticas.

Ahora, lo que es complicado, es que en lenguajes dinámicos como PHP, todos tienen un valor en un contexto booleano , que (en PHP) esFalse .

Si lo prueba con ==, está probando el valor booleano, por lo que obtendrá igualdad. Si lo pruebas con=== , probará el tipo y obtendrá desigualdad.

Entonces, ¿por qué son útiles?

Bueno, mira la strrpos()función. ¡Devuelve False si no encontró nada, pero 0 si ha encontrado algo al comienzo de la cadena!

<?php
// pitfall :
if (strrpos("Hello World", "Hello")) { 
    // never exectuted
}

// smart move :
if (strrpos("Hello World", "Hello") !== False) {
    // that works !
}
?>

Y, por supuesto, si trata con estados:

Desea hacer una diferencia entre DebugMode = False(establecer en apagado), DebugMode = True(establecer en encendido) y DebugMode = Null(no establecer en absoluto, conducirá a una depuración difícil ;-)).

e-satis
fuente
39
Nota sobre Null: PHP lo usa como "sin valor", pero no es un buen hábito. En general, Nulo significa "valor desconocido" que es diferente de "sin valor" o "variable no inicializada". Nada más 1 es 1, mientras que un valor desconocido más uno es un valor desconocido. Solo recuerde que cualquier operador aplicado a nulo (debería) resultará en nulo, porque cualquier operación en un "valor desconocido" da como resultado un valor desconocido.
Eli
77
tenga en cuenta que esto es todo intenciones . nada que ver con lo que sucede en la realidad. en realidad, una función puede devolver falso para valores inexistentes (por ejemplo, strpos, input_filter) y nulo para falla (por ejemplo, input_filter). entonces la respuesta es, use === falso y / o === nulo, después de leer esa documentación de función particular.
gcb
55
@Eli: ¿de dónde sacas la idea de que Nulo significa "valor desconocido" en general. No puedo pensar en ningún lenguaje de computadora donde esto sea cierto, ni significa que en inglés, al menos no de acuerdo con alguna definición que pueda encontrar o haya escuchado. ¿Quizás sabes algo que yo no sé?
iconoclasta
2
@iconoclast - Lo estoy tomando del mundo de la base de datos. Según tengo entendido, nulo se utiliza como marcador de posición para un valor de datos que no existe en la base de datos o es desconocido. Ver dev.mysql.com/doc/refman/5.0/en/working-with-null.html o en.wikipedia.org/wiki/Null_%28SQL%29 .
Eli
2
Eli no está mal. Está afirmando que semánticamente, cuando usa nulo, le indica a otros programadores que no sabe qué hay allí. Es indefinido Mientras que cuando usas 0, indicas que sabes lo que hay allí: un número. Y aquí el número representa la ausencia de cosas. Recuerde que no importa cómo los valores de amenazas PHP, los valores tienen un significado, los valores son una forma de documentación.
e-satis
45

nulles null. falseesfalse . Triste pero cierto.

No hay mucha consistencia en PHP. los desarrolladores intentan hacer nulo significa "desconocido" o "inexistente". pero a menudo False servirá como 'inexistente' (por ejemplo, strrpos ('fail', 'search') devolverá falso y no nulo)

a menudo verá que se usa nulo cuando ya están usando falso para algo. Por ejemplo, filter_input (). Devuelven falso si la variable falla el filtro. y nulo si la variable no existe (no existe significa que también falló el filtro? entonces, ¿por qué incluso devolver nulo?!?)

php tiene la conveniencia de devolver datos en las funciones. y a menudo los desarrolladores se atiborran de todo tipo de estado de falla en lugar de los datos.

Y no hay una manera sensata en PHP para detectar datos (int, str, etc.) de la falla (falso, nulo)

prácticamente tiene que probar siempre === nulo o === falso, dependiendo de la función. o para ambos, en casos como filter_input () / filter_var ()

y aquí hay un poco de diversión con el malabarismo de tipos. ni siquiera incluye matrices y objetos.

var_dump( 0<0 );        #bool(false)
var_dump( 1<0 );        #bool(false)
var_dump( -1<0 );       #bool(true)
var_dump( false<0 );    #bool(false)
var_dump( null<0 );     #bool(false)
var_dump( ''<0 );       #bool(false)
var_dump( 'a'<0 );      #bool(false)
echo "\n";
var_dump( !0 );        #bool(true)
var_dump( !1 );        #bool(false)
var_dump( !-1 );       #bool(false)
var_dump( !false );    #bool(true)
var_dump( !null );     #bool(true)
var_dump( !'' );       #bool(true)
var_dump( !'a' );      #bool(false)
echo "\n";
var_dump( false == 0 );        #bool(true)
var_dump( false == 1 );        #bool(false)
var_dump( false == -1 );       #bool(false)
var_dump( false == false );    #bool(true)
var_dump( false == null );     #bool(true)
var_dump( false == '' );       #bool(true)
var_dump( false == 'a' );      #bool(false)
echo "\n";
var_dump( null == 0 );        #bool(true)
var_dump( null == 1 );        #bool(false)
var_dump( null == -1 );       #bool(false)
var_dump( null == false );    #bool(true)
var_dump( null == null );     #bool(true)
var_dump( null == '' );       #bool(true)
var_dump( null == 'a' );      #bool(false)
echo "\n";
$a=0; var_dump( empty($a) );        #bool(true)
$a=1; var_dump( empty($a) );        #bool(false)
$a=-1; var_dump( empty($a) );       #bool(false)
$a=false; var_dump( empty($a) );    #bool(true)
$a=null; var_dump( empty($a) );     #bool(true)
$a=''; var_dump( empty($a) );       #bool(true)
$a='a'; var_dump( empty($a));      # bool(false)
echo "\n"; #new block suggested by @thehpi
var_dump( null < -1 ); #bool(true)
var_dump( null < 0 ); #bool(false)
var_dump( null < 1 ); #bool(true)
var_dump( -1 > true ); #bool(false)
var_dump( 0 > true ); #bool(false)
var_dump( 1 > true ); #bool(true)
var_dump( -1 > false ); #bool(true)
var_dump( 0 > false ); #bool(false)
var_dump( 1 > true ); #bool(true)
gcb
fuente
24
en mi opinión 0 == nulo es absurdo absoluto, ya que 0 es un valor y nulo es un indicador que muestra que la variable no está inicializada. Gracias equipo php
mercsen
1
Repetiste dos veces tu sección de código comenzando con var_dump( null == 0 );.
Sparky
2
lo que es realmente extraño en php: nulo <-1 => VERDADERO
thehpi
1
@mercsen Por lo menos si PHP se comportó consistentemente como 0 == nulo, hubiera estado bien con eso. Curiosamente, 0 == nully null == [], pero [] != 0!!
nawfal
1
strrpos('fail', 'search') will return false, and not nullen mi opinión es correcto: si nullsignifica desconocido, entonces strrposregresar nullsería como decir 'No sé si la cadena está allí' en lugar de 'La cadena no está allí'.
Eborbob
22

A continuación se muestra un ejemplo:

            Comparisons of $x with PHP functions

Expression          gettype()   empty()     is_null()   isset() boolean : if($x)
$x = "";            string      TRUE        FALSE       TRUE    FALSE
$x = null;          NULL        TRUE        TRUE        FALSE   FALSE
var $x;             NULL        TRUE        TRUE        FALSE   FALSE
$x is undefined     NULL        TRUE        TRUE        FALSE   FALSE
$x = array();       array       TRUE        FALSE       TRUE    FALSE
$x = false;         boolean     TRUE        FALSE       TRUE    FALSE
$x = true;          boolean     FALSE       FALSE       TRUE    TRUE
$x = 1;             integer     FALSE       FALSE       TRUE    TRUE
$x = 42;            integer     FALSE       FALSE       TRUE    TRUE
$x = 0;             integer     TRUE        FALSE       TRUE    FALSE
$x = -1;            integer     FALSE       FALSE       TRUE    TRUE
$x = "1";           string      FALSE       FALSE       TRUE    TRUE
$x = "0";           string      TRUE        FALSE       TRUE    FALSE
$x = "-1";          string      FALSE       FALSE       TRUE    TRUE
$x = "php";         string      FALSE       FALSE       TRUE    TRUE
$x = "true";        string      FALSE       FALSE       TRUE    TRUE
$x = "false";       string      FALSE       FALSE       TRUE    TRUE

Consulte esto para obtener más referencias de comparaciones de tipos en PHP. Debería darte una comprensión clara.

KristCont
fuente
5

En PHP puede usar los operadores === y! == para verificar no solo si los valores son iguales sino también si sus tipos coinciden. Entonces, por ejemplo: 0 == falsees true, pero 0 === falsees false. Lo mismo vale para !=versus !==. Además, en caso de que se compare nullcon los otros dos utilizando los operadores mencionados, espere resultados similares.

Ahora, en PHP, esta calidad de valores se usa generalmente cuando se devuelve un valor que a veces puede ser 0(cero), pero a veces puede ser que la función haya fallado. En tales casos en PHP, usted regresa falsey debe verificar estos casos utilizando el operador de identidad ===. Por ejemplo, si está buscando una posición de una cadena dentro de la otra y está usando strpos(), esta función devolverá la posición numérica que puede ser 0 si la cadena se encuentra al principio, pero si la cadena no se encuentra en todo, luego strpos()regresará falsey tendrá que tener esto en cuenta al tratar con el resultado.

Si utilizará la misma técnica en sus funciones, cualquier persona familiarizada con la biblioteca PHP estándar comprenderá lo que está sucediendo y cómo verificar si el valor devuelto es el deseado o si ocurrió algún error durante el procesamiento. Lo mismo ocurre con los parámetros de función, puede procesarlos de manera diferente dependiendo de si son matrices o cadenas o no, y esta técnica también se usa en todo PHP, por lo que todo el mundo lo entenderá con bastante facilidad. Así que supongo que ese es el poder.

inkredibl
fuente
5

Falso, Nulo, Nada, 0, Indefinido , etc., etc.

Cada uno de estos tiene significados específicos que se correlacionan con conceptos reales. A veces se sobrecargan múltiples significados en una sola palabra clave o valor.

En C y C ++ , NULL, Falsey 0están sobrecargados en el mismo valor. En C # son 3 conceptos distintos.

nullo NULLgeneralmente indica una falta de valor, pero generalmente no especifica por qué. 0indica el número cero natural y tiene una equivalencia de tipo a 1, 2, 3, etc. y en idiomas que admiten conceptos separados, NULLsolo se debe tratar un número.

Falso indica no verdad. Y se usa en valores binarios . No quiere decir que no esté definido, ni tampoco 0. Simplemente indica uno de los dos valores binarios.

Nada puede indicar que el valor se establece específicamente en nada, lo que indica lo mismo que nulo, pero con intención.

Sin definir en algunos idiomas indica que el valor aún no se ha establecido porque ningún código ha especificado un valor real.

Orion Adrian
fuente
Interesante, tal vez, pero no discute PHP en absoluto.
Brad
4

Sólo he perdido medio día tratando de obtener ya sea una 0, null, falsepara volver a strops!

Esto es todo lo que estaba tratando de hacer, antes de encontrar que la lógica no fluía en la dirección correcta, pareciendo que había un agujero negro en la codificación php:

Concept tome un nombre de dominio alojado en un servidor y asegúrese de que no sea de nivel raíz, OK, hay varias formas diferentes de hacerlo, pero elegí diferente debido a otras funciones / construcciones php que he hecho.

De todos modos, aquí estaba la base del costeo:

if (strpos($_SERVER ['SERVER_NAME'], dirBaseNAME ()) 
{ 
    do this 
} else {
    or that
}

{
echo strpos(mydomain.co.uk, mydomain);  

if ( strpos(mydomain, xmas) == null ) 
    {
        echo "\n1 is null"; 
    }

if ( (strpos(mydomain.co.uk, mydomain)) == 0 ) 
    {
        echo "\n2 is 0"; 
    } else {
        echo "\n2 Something is WRONG"; 
    }

if ( (mydomain.co.uk, mydomain)) != 0 ) 
    {
        echo "\n3 is 0"; 
    } else {
        echo "\n3 it is not 0"; 
    }

if ( (mydomain.co.uk, mydomain)) == null ) 
    {
        echo "\n4 is null"; 
    } else {
        echo "\n4 Something is WRONG"; 
    }
}

¡FINALMENTE después de leer este tema, descubrí que esto funcionó!

{
if ((mydomain.co.uk, mydomain)) !== false ) 
    {
        echo "\n5 is True"; 
    } else {
        echo "\n5 is False"; 
    }
}

Gracias por este artículo, ahora entiendo que aunque sea Navidad, puede que no sea Navidad false, ¡ya que también puede ser un NULLdía!

Después de perder un día depurando un código simple, deseé haberlo sabido antes, ya que habría podido identificar el problema, en lugar de ir por todos lados tratando de hacer que funcione. No funcionó, como False, NULLy 0no son todos iguales True or False or NULL?

madesignUK
fuente
2

De la documentación en línea de PHP :

Para convertir explícitamente un valor a booleano, use los moldes (bool) o (boolean).
Sin embargo, en la mayoría de los casos la conversión es innecesaria, ya que un valor se convertirá automáticamente si un operador, función o estructura de control requiere un argumento booleano.
Al convertir a booleano, los siguientes valores se consideran FALSOS:

  • el FALSEpropio booleano
  • el entero `` 0 (cero)
  • el flotador 0.0(cero)
  • la cadena vacía y la cadena "0"
  • una matriz con cero elementos
  • un objeto con cero variables miembro (solo PHP 4)
  • el tipo especial NULL(incluidas las variables no definidas)
  • Objetos SimpleXML creados a partir de etiquetas vacías
    Se considera TRUEcualquier otro valor (incluido cualquier recurso).

Entonces, en la mayoría de los casos, es lo mismo.

Por otro lado, el ===y el ==no son lo mismo. Regularmente, solo necesita el operador "igual". Para aclarar:

$a == $b    //Equal. TRUE if $a is equal to $b.
$a === $b   //Identical. TRUE if $a is equal to $b, and they are of the same type. 

Para obtener más información, consulte " Operadores de comparación página " " en los documentos en línea de PHP.

Espero que esto ayude.

Javier Constanzo
fuente
1

Las diferencias entre estos valores siempre se reducen a reglas detalladas específicas del idioma. Lo que aprende para PHP no es necesariamente cierto para Python, Perl o C, etc. Si bien es valioso aprender las reglas para los idiomas con los que está trabajando, confiar demasiado en ellas es un problema . El problema surge cuando el próximo programador necesita mantener su código y ha utilizado alguna construcción que aprovecha algunos pequeños detalles de Nulo vs. Falso (por ejemplo). Su código debe verse correcto (y por el contrario, el código incorrecto debe verse mal ).

Greg Hewgill
fuente
1

Nulo se utiliza en bases de datos para representar "sin registro" o "sin información". Por lo tanto, es posible que tenga un campo de bits que describe "¿quiere este usuario que le enviemos correos electrónicos?", Donde Verdadero significa que sí, Falso significa que no quiere que se le envíe nada, pero Nulo significa que usted no No lo se. Pueden surgir a través de uniones externas y similares.

Las implicaciones lógicas de Null son a menudo diferentes: en algunos idiomas, NULL no es igual a nada, por lo que si (a == NULL) siempre será falso.

Entonces, personalmente, siempre inicializaría un booleano en FALSO, e inicializar uno en NULL se vería un poco repulsivo (incluso en C, donde ambos son solo 0 ... solo una cosa de estilo).

Peter
fuente
1

Creo que los malos desarrolladores encuentran todos los usos diferentes de nulo / 0 / falso en su código.

Por ejemplo, uno de los errores más comunes que cometen los desarrolladores es devolver el código de error en forma de datos con una función.

// On error GetChar returns -1
int GetChar()

Este es un ejemplo de una interfaz de azúcar. Esto se explica en el libro "Depuración del proceso de desarrollo de software" y también en otro libro "escritura del código correcto".

El problema con esto, es la implicación o suposiciones hechas en el tipo char. En algunos compiladores, el tipo char no puede estar firmado. Entonces, aunque devuelva un -1, el compilador puede devolver 1 en su lugar. Este tipo de supuestos del compilador en C ++ o C son difíciles de detectar.

En cambio, la mejor manera es no mezclar el código de error con sus datos. Entonces la siguiente función.

char GetChar()

ahora se convierte

// On success return 1
// on failure return 0
bool GetChar(int &char)

Esto significa que no importa cuán joven sea el desarrollador en su tienda de desarrollo, él o ella nunca se equivocarán. Aunque esto no se trata de reducción o dependencias en el código.

Entonces, en general, intercambiar bool como el tipo de primera clase en el idioma está bien y creo que Joel habló sobre eso con su reciente postcast. Pero trate de no usar combinaciones de combinación y combinación con sus datos en sus rutinas y debería estar perfectamente bien.

Chad
fuente
1

En PHP depende de si está validando tipos:

( 
 ( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) &&
 ( false !== null ) && ( false == null ) 
)

Técnicamente nulo es 0x00pero en PHP ( null == 0x00 ) && ( null !== 0x00 ).

0 es un valor entero

Gavin M. Roy
fuente
1

Un hecho interesante sobre NULLPHP: si establece una var igual a NULL, es lo mismo que si la hubiera llamado unset().

NULLesencialmente significa que una variable no tiene ningún valor asignado; falsees un valor booleano válido, 0es un valor entero válido, y PHP tiene algunas conversiones bastante feas entre 0, "0", "", y false.

lado de tierra
fuente
0

Nulo no es nada, Falso es un bit y 0 es (probablemente) 32 bits.

No soy un experto en PHP, pero en algunos de los lenguajes más modernos no son intercambiables. Extraño que tener 0 y false sean intercambiables, pero con boolean como un tipo real, puede tener métodos y objetos asociados, por lo que eso es solo una compensación. Sin embargo, nulo es nulo, la ausencia de algo esencialmente.

CodeRedick
fuente
0

Bueno, no recuerdo lo suficiente de mis días de PHP para responder la parte "===", pero para la mayoría de los lenguajes de estilo C, NULL debe usarse en el contexto de valores de puntero, falso como booleano y cero como valor numérico como un int. '\ 0' es el valor habitual para un contexto de caracteres. Por lo general, también prefiero usar 0.0 para flotadores y dobles.

Entonces ... la respuesta rápida es: contexto.

jasonmray
fuente
0

En casi todos los lenguajes modernos, nulo se refiere lógicamente a punteros (o referencias) que no tienen un valor o una variable que no se inicializa. 0 es el valor entero de cero, y falso es el valor booleano de, bueno, falso. Para complicar las cosas, en C, por ejemplo, nulo, 0 y falso se representan exactamente de la misma manera. No sé cómo funciona en PHP.

Luego, para complicar más las cosas, las bases de datos tienen un concepto de nulo, lo que significa que faltan o no son aplicables, y la mayoría de los lenguajes no tienen una forma directa de asignar un DBNull a su nulo. Hasta hace poco, por ejemplo, no había distinción entre un int que era nulo y cero, pero eso se cambió con ints anulables.

Lamento hacer que esto suene complicado. Es solo que este ha sido un punto difícil en los idiomas durante años, y hasta hace poco, no había tenido una resolución clara en ninguna parte. La gente solía simplemente juntar cosas o dejar en blanco o 0 representar nulos en la base de datos, lo que no siempre funciona demasiado bien.

Charles Graham
fuente
0

Falso y 0 son conceptualmente similares, es decir, son isomorfos. 0 es el valor inicial para el álgebra de números naturales, y False es el valor inicial para el álgebra booleana.

En otras palabras, 0 puede definirse como el número que, cuando se agrega a algún número natural, produce ese mismo número:

x + 0 = x

Del mismo modo, False es un valor tal que una disyunción de él y cualquier otro valor es el mismo valor:

x || False = x

Nulo es conceptualmente algo totalmente diferente. Dependiendo del idioma, existen diferentes semánticas para él, pero ninguna de ellas describe un "valor inicial" como Falso y 0 son. No hay álgebra para Null. Se refiere a variables, generalmente para denotar que la variable no tiene un valor específico en el contexto actual. En la mayoría de los idiomas, no hay operaciones definidas en Null, y es un error usar Null como operando. En algunos idiomas, hay un valor especial llamado "fondo" en lugar de "nulo", que es un marcador de posición para el valor de un cálculo que no termina.

He escrito más extensamente sobre las implicaciones de NULL en otros lugares.

Apocalipsis
fuente
1
offtopic, false == 0 está completamente retrasado. Más aún con php que devuelve datos O falla en una función. ver el retorno de mysql_insert_id. "" "El ID generado para una columna AUTO_INCREMENT por la consulta anterior en caso de éxito, 0 si la consulta anterior no genera un valor AUTO_INCREMENT, o FALSE si no se estableció una conexión MySQL." "" Básicamente puede devolver A) el ID, B) cero, C) falso ... ahora si ese es el primer elemento de la tabla, ¡la identificación será cero! ¡entonces los tres valores son iguales! ¿Cómo puede el desarrollador dar sentido a tres tipos de ceros? ... y estoy de acuerdo con tu publicación en nulo.
gcb
0

¿Alguien puede explicarme por qué 'NULL' no es solo una cadena en una instancia de comparación?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!
vladzur
fuente
1
Porque PHP convierte internamente al tipo entero y luego se compara. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)ver php.net/manual/en/language.operators.comparison.php Traducir cadenas y recursos a números, matemática habitual
Sevyls
-1

Los problemas con la falsedad provienen de la historia de PHP. El problema se dirige al tipo escalar no bien definido.

'*' == true -> true (string match)
'*' === true -> false (numberic match)

(int)'*' == true -> false
(string)'*' == true -> true

La rigurosidad de PHP7 es un paso adelante, pero tal vez no sea suficiente. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

adrian
fuente