Null vs. False vs. 0 in PHP


146

Mi è stato detto che i buoni sviluppatori possono individuare / utilizzare la differenza tra Nulle Falseed 0e tutti gli altri buoni entità "niente".
Qual è la differenza, in particolare in PHP? Ha qualcosa a che fare con ===?


È quasi impossibile capire davvero quando viene utilizzato. Immagino sia importante che tu sia COERENTE quando lo usi nulle quando false. I preferiscono utilizzare nulldurante il recupero di un valore da un metodo, perché posso usare issetper determinare se un valore viene restituito invece di usare emptyche non prenderà in considerazione: false, 0, '0'o una stringa vuota, che può essere valori vitali in molte situazioni. Per me è la soluzione più pulita in un costrutto disordinato.
JMRC,

Risposte:


221

È specifico della lingua, ma in PHP:

Nullsignifica " niente ". Il var non è stato inizializzato.

Falsesignifica " non vero in un contesto booleano ". Utilizzato per mostrare esplicitamente che hai a che fare con problemi logici.

0è un int. Niente a che vedere con il resto sopra, usato per la matematica.

Ora, ciò che è difficile, è che in linguaggi dinamici come PHP, tutti hanno un valore in un contesto booleano , che è (in PHP) False.

Se lo provi ==, sta testando il valore booleano, quindi otterrai l'uguaglianza. Se lo provi con ===, testerà il tipo e otterrai disuguaglianza.

Quindi perché sono utili?

Bene, guarda la strrpos()funzione. Restituisce False se non ha trovato nulla, ma 0 se ha trovato qualcosa all'inizio della stringa!

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

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

E ovviamente, se hai a che fare con gli stati:

Volete fare la differenza tra DebugMode = False(impostato su off), DebugMode = True(impostato su on) e DebugMode = Null(non impostato affatto, porterà a un duro debug ;-)).


39
Nota su Null: PHP lo usa come "nessun valore", ma questa non è una buona abitudine per entrare. In generale, Null significa "valore sconosciuto" che è diverso da "nessun valore" o "variabile non inizializzata". Niente più 1 è 1, mentre un valore sconosciuto più uno è un valore sconosciuto. Basta ricordare che qualsiasi operatore applicato a null comporterà (dovrebbe) null, poiché qualsiasi operazione su un "valore sconosciuto" comporta un valore sconosciuto.
Eli,

7
tieni presente che queste sono tutte le intenzioni . niente a che fare con ciò che accade nella realtà. in realtà una funzione può restituire false per valori inesistenti (ad esempio strpos, input_filter) e null per errore (ad esempio input_filter). quindi la risposta è, usare === false e / o === null, dopo aver letto la documentazione di quella particolare funzione.
gcb,

5
@Eli: da dove viene l'idea che Null significa "valore sconosciuto" in generale. Non riesco a pensare a nessun linguaggio informatico in cui questo sia vero, né significa che in inglese, almeno non secondo una definizione che posso trovare o che ho sentito. Forse sai qualcosa che non conosco?
iconoclasta,

2
@iconoclast - Lo sto prendendo dal mondo del database. A quanto ho capito, null è usato come segnaposto per un valore di dati che non esiste nel database o è sconosciuto. Vedi dev.mysql.com/doc/refman/5.0/en/working-with-null.html o en.wikipedia.org/wiki/Null_%28SQL%29 .
Eli,

2
Eli non ha torto. Lo afferma semanticamente, quando usi null, segnali ad altri programmatori che non sai cosa c'è dentro. Non è definito. Mentre quando usi 0, segnali che sai cosa c'è dentro: un numero. E qui il numero rappresenta l'assenza di cose. Ricorda che, indipendentemente dal modo in cui PHP minaccia i valori, i valori hanno un significato, i valori sono una forma di documentazione.
e-satis

45

nulllo è null. falselo è false. Triste ma vero.

non c'è molta coerenza in PHP. gli sviluppatori TENTANO di rendere null significa "sconosciuto" o "inesistente". ma spesso False fungerà da "inesistente" (ad es. strrpos ("fail", "search") restituirà false e non null)

vedrai spesso null essere usato quando stanno già usando false per qualcosa. ad esempio filter_input (). Restituiscono false se la variabile non riesce al filtro. e null se la variabile non esiste (non esiste significa che ha anche fallito il filtro? quindi perché anche restituire null?!?)

php ha la comodità di restituire dati nelle funzioni. e spesso gli sviluppatori stipano tutti i tipi di stato di errore invece dei dati.

E in PHP non esiste alcun modo sano di rilevare i dati (int, str, ecc.) Da errori (false, null)

praticamente devi sempre testare === null o === false, a seconda della funzione. o per entrambi, in casi come filter_input () / filter_var ()

ed ecco un po 'di divertimento con la giocoleria di tipo. nemmeno includendo matrici e oggetti.

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)

24
nella mia opinione 0 == null è un'assurdità assoluta, poiché 0 è un valore e null è un flag che mostra che la variabile non è inizializzata. Grazie squadra php
mercsen,

1
Hai ripetuto due volte la tua sezione di codice a partire da var_dump( null == 0 );.
Sparky

2
ciò che è veramente strano in php: null <-1 => TRUE
thehpi il

1
@mercsen Almeno se PHP si fosse comportato in modo coerente come 0 == null sarei andato bene con esso. Stranamente, 0 == nulle null == [], ma [] != 0!!
nawfal,

1
strrpos('fail', 'search') will return false, and not nullsecondo me è corretto - se nullsignifica sconosciuto, allora strrpostornare nullsarebbe come dire "Non so se la stringa è lì" piuttosto che "La stringa non è lì".
Eborbob,

22

Di seguito è riportato un esempio:

            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

Si prega di vedere questo per ulteriori riferimenti ai confronti dei tipi in PHP. Dovrebbe darti una chiara comprensione.


5

In PHP puoi usare gli operatori === e! == per verificare non solo se i valori sono uguali ma anche se i loro tipi corrispondono. Quindi per esempio: 0 == falseè true, ma 0 === falseè false. Lo stesso vale per !=contro !==. Anche nel caso in cui ti confronti nullcon gli altri due usando gli operatori citati, aspettati risultati simili.

Ora in PHP questa qualità di valori viene solitamente utilizzata quando si restituisce un valore che a volte può essere 0(zero), ma a volte potrebbe essere che la funzione non sia riuscita. In tali casi in PHP ritorni falsee devi controllare questi casi usando l'operatore di identità ===. Ad esempio, se stai cercando una posizione di una stringa all'interno dell'altra e stai utilizzando strpos(), questa funzione restituirà la posizione numerica che può essere 0 se la stringa viene trovata all'inizio, ma se la stringa non si trova in tutto, quindi strpos()tornerà falsee devi tenerne conto quando ti occupi del risultato.

Se utilizzerai la stessa tecnica nelle tue funzioni, chiunque abbia familiarità con la libreria PHP standard capirà cosa sta succedendo e come verificare se il valore restituito è ciò che si desidera o si è verificato un errore durante l'elaborazione. Lo stesso vale per i parametri di funzione, puoi elaborarli in modo diverso a seconda che siano array o stringhe o cosa no, e questa tecnica viene utilizzata anche in tutto il PHP pesantemente, quindi tutti lo capiranno abbastanza facilmente. Quindi immagino sia questo il potere.


5

False, Null, Nothing, 0, Undefined , ecc., Ecc.

Ognuno di questi ha significati specifici correlati con concetti reali. A volte più significati sono sovraccaricati in una singola parola chiave o valore.

In C e C ++ , NULL, Falsee 0sono sovraccarichi allo stesso valore. In C # sono 3 concetti distinti.

nullo di NULLsolito indica una mancanza di valore, ma di solito non specifica il perché. 0indica il numero zero naturale e ha l'equivalenza del tipo a 1, 2, 3, ecc. e nelle lingue che supportano concetti separati di NULLdovrebbe essere trattato solo un numero.

Falso indica non verità. E utilizzato in valori binari . Non significa disinserito, né significa 0. Indica semplicemente uno dei due valori binari.

Nulla può indicare che il valore è specificamente impostato per essere nulla che indica la stessa cosa di null, ma con intento.

Non definito in alcune lingue indica che il valore deve ancora essere impostato perché nessun codice ha specificato un valore effettivo.


Interessante, forse, ma non discute affatto di PHP.
Brad,

4

Ho appena sprecato 1/2 giornata cercando di ottenere sia una 0, null, falseper tornare da strops!

Ecco tutto quello che stavo cercando di fare, prima di scoprire che la logica non scorreva nella giusta direzione, sembrando che ci fosse un buco nero nella codifica php:

Il concetto prende un nome di dominio ospitato su un server e si assicura che non sia a livello di root, OK diversi modi per farlo, ma ho scelto diversi a causa di altre funzioni / costrutti php che ho fatto.

Comunque qui è stata la base della cosing:

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 dopo aver letto questo argomento, ho scoperto che ha funzionato !!!

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

Grazie per questo articolo, ora capisco che anche se è Natale, potrebbe non essere Natale come false, poiché può anche essere un NULLgiorno!

Dopo aver perso una giornata di debug di alcuni semplici codici, avrei voluto saperlo prima, dato che avrei potuto identificare il problema, piuttosto che andare ovunque cercando di farlo funzionare. Non ha funzionato, come False, NULLe 0non sono tutti uguali a True or False or NULL?


2

Dalla documentazione online di PHP :

Per convertire esplicitamente un valore in booleano, utilizzare i cast (boolean) o (boolean).
Tuttavia, nella maggior parte dei casi il cast non è necessario, poiché un valore verrà automaticamente convertito se un operatore, una funzione o una struttura di controllo richiedono un argomento booleano.
Quando si converte in booleano, i seguenti valori sono considerati FALSI:

  • il booleano FALSEstesso
  • l'intero `` 0 (zero)
  • il galleggiante 0.0(zero)
  • la stringa vuota e la stringa "0"
  • un array con zero elementi
  • un oggetto con zero variabili membro (solo PHP 4)
  • il tipo speciale NULL(comprese le variabili non impostate)
  • Oggetti SimpleXML creati da tag vuoti
    Viene considerato ogni altro valore TRUE(compresa qualsiasi risorsa).

Quindi, nella maggior parte dei casi, è lo stesso.

D'altra parte, il ===e il ==non sono la stessa cosa. Regolarmente, hai solo bisogno dell'operatore "uguale". Chiarire:

$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. 

Per ulteriori informazioni, controlla la pagina " Operatori di confronto " nei documenti online di PHP.

Spero che questo ti aiuti.


1

Le differenze tra questi valori dipendono sempre da regole dettagliate specifiche della lingua. Quello che impari per PHP non è necessariamente vero per Python, o Perl, o C, ecc. Mentre è utile imparare le regole per la lingua o le lingue con cui stai lavorando, fare troppo affidamento su di esse è chiedere problemi . Il problema sorge quando il prossimo programmatore deve mantenere il tuo codice e hai usato un costrutto che sfrutta alcuni piccoli dettagli di Null vs. False (ad esempio). Il codice dovrebbe apparire corretto (e viceversa, il codice sbagliato dovrebbe apparire sbagliato ).


1

Null viene utilizzato nei database per rappresentare "nessun record" o "nessuna informazione". Quindi potresti avere un piccolo campo che descrive "questo utente vuole che ci vengano inviate e-mail da noi", dove True significa che lo fanno, False significa che non vogliono ricevere nulla, ma Null significherebbe che non devi ' non lo so. Possono verificarsi attraverso join esterni e simili.

Le implicazioni logiche di Null sono spesso diverse: in alcune lingue NULL non è uguale a nulla, quindi se (a == NULL) sarà sempre falso.

Quindi personalmente avrei sempre inizializzato un booleano su FALSE, e inizializzarne uno su NULL sarebbe sembrato un po 'icky (anche in C dove i due sono entrambi solo 0 ... solo una cosa di stile).


1

Penso che i cattivi sviluppatori trovino tutti i diversi usi di null / 0 / false nel codice lì.

Ad esempio, uno degli errori più comuni che gli sviluppatori commettono è quello di restituire il codice di errore sotto forma di dati con una funzione.

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

Questo è un esempio di un'interfaccia Sugar. Questo è spiegato nel libro "Debug del processo di sviluppo del software" e anche in un altro libro "scrivere il codice corretto".

Il problema con questo, è l'implicazione o le ipotesi fatte sul tipo di carattere. Su alcuni compilatori il tipo di carattere può essere non firmato. Quindi, anche se si restituisce un -1, il compilatore può invece restituire 1. Questo tipo di ipotesi del compilatore in C ++ o C sono difficili da individuare.

Invece, il modo migliore è non mescolare il codice di errore con i tuoi dati. Quindi la seguente funzione.

char GetChar()

ora diventa

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

Ciò significa che non importa quanto sia giovane lo sviluppatore nel tuo negozio di sviluppo, non sbaglierà mai. Anche se non si tratta di ridondanza o dipendenze nel codice.

Quindi, in generale, scambiare bool come il primo tipo di classe nella lingua va bene e penso che Joel ne abbia parlato con il suo recente postcast. Ma cerca di non usare i bool mix and match con i tuoi dati nelle tue routine e dovresti stare perfettamente bene.


1

In PHP dipende se stai convalidando i tipi:

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

Tecnicamente null è 0x00ma in PHP ( null == 0x00 ) && ( null !== 0x00 ).

0 è un valore intero.


1

Un fatto interessante riguardo NULLa PHP: se imposti un var uguale a NULL, è lo stesso che se lo avessi chiamato unset().

NULLessenzialmente significa che una variabile non ha alcun valore assegnato ad essa; falseè un valore booleano valido, 0è un valore intero valido, e PHP ha alcune piuttosto brutti conversioni tra 0, "0", "", e false.


0

Null è nulla, False è un bit e 0 è (probabilmente) 32 bit.

Non un esperto di PHP, ma in alcune delle lingue più moderne non sono intercambiabili. Mi manca un po 'avere 0 e false essere intercambiabili, ma con il booleano come un tipo reale puoi avere metodi e oggetti associati ad esso, quindi questo è solo un compromesso. Nulla è nulla, l'assenza di qualcosa essenzialmente.


0

Beh, non ricordo abbastanza dai miei giorni di PHP per rispondere alla parte "===", ma per la maggior parte dei linguaggi in stile C, NULL dovrebbe essere usato nel contesto dei valori del puntatore, falso come booleano e zero come un valore numerico come un int. '\ 0' è il valore abituale per un contesto di carattere. Di solito preferisco anche usare 0,0 per float e doppi.

Quindi .. la risposta rapida è: contesto.


0

In quasi tutte le lingue moderne, null logicamente riferisce a puntatori (o riferimenti) che non hanno un valore o a una variabile non inizializzata. 0 è il valore intero di zero e false è il valore booleano di, beh, falso. Per complicare le cose, in C, ad esempio, null, 0 e false sono tutti rappresentati esattamente allo stesso modo. Non so come funziona in PHP.

Quindi, per complicare ulteriormente le cose, i database hanno un concetto di null, il che significa che manca o non è applicabile, e la maggior parte delle lingue non ha un modo diretto per mappare un DBNull al loro null. Fino a poco tempo fa, ad esempio, non vi era alcuna distinzione tra un int che era nullo e uno zero, ma ciò è stato modificato con nulli ints.

Mi dispiace rendere questo suono complicato. È solo che questo è stato un punto critico nelle lingue per anni e fino a poco tempo fa non ha avuto una chiara risoluzione da nessuna parte. Le persone usavano semplicemente raggruppare le cose insieme o rendere vuoti o 0 rappresentare null nel database, che non sempre funziona troppo bene.


0

False e 0 sono concettualmente simili, cioè sono isomorfi. 0 è il valore iniziale per l'algebra dei numeri naturali e False è il valore iniziale per l'algebra booleana.

In altre parole, 0 può essere definito come il numero che, se aggiunto a un numero naturale, produce lo stesso numero:

x + 0 = x

Allo stesso modo, False è un valore tale che una disgiunzione di esso e qualsiasi altro valore è lo stesso valore:

x || False = x

Null è concettualmente qualcosa di completamente diverso. A seconda della lingua, esistono diverse semantiche, ma nessuna di esse descrive un "valore iniziale" come False e 0. Non esiste algebra per Null. Riguarda le variabili, di solito per indicare che la variabile non ha alcun valore specifico nel contesto corrente. Nella maggior parte delle lingue, non ci sono operazioni definite su Null ed è un errore utilizzare Null come operando. In alcune lingue, esiste un valore speciale chiamato "bottom" anziché "null", che è un segnaposto per il valore di un calcolo che non termina.

Ho scritto più ampiamente sulle implicazioni di NULL altrove.


1
offtopic, false == 0 è completamente ritardato. Ancora di più con php che restituisce dati o guasti in una funzione. vedere il ritorno per mysql_insert_id. "" "L'ID generato per una colonna AUTO_INCREMENT dalla query precedente in caso di successo, 0 se la query precedente non genera un valore AUTO_INCREMENT o FALSE se non è stata stabilita alcuna connessione MySQL." "" In pratica può restituire A) l'id, B) zero, C) false ... ora se questo è il primo elemento nella tabella, id sarà zero! quindi tutti e tre i valori sono uguali! come può lo sviluppatore dare un senso a tre tipi di zero? ... e sono d'accordo con il tuo post su null.
gcb,

0

Qualcuno può spiegarmi perché 'NULL' non è solo una stringa in un'istanza di confronto?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!

1
Perché PHP esegue il cast internamente al tipo intero e confronta quindi. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)vedi php.net/manual/it/language.operators.comparison.php Traduci stringhe e risorse in numeri, matematica normale
Sevyls

-1

I problemi con la falsità provengono dalla storia di PHP. Il problema riguarda il tipo scalare non ben definito.

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

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

Il rigore di PHP7 è un passo avanti, ma forse non abbastanza. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.