Null vs False vs 0 en PHP

146

On me dit que les bons développeurs peuvent repérer / utiliser la différence entre Nullet Falseet 0et toutes les autres bonnes entités «rien».
Quelle est la différence, en particulier en PHP? Cela a-t-il quelque chose à voir avec ===?

stalepretzel
la source
Il est presque impossible de vraiment savoir quand ce qui est utilisé. Je suppose qu'il est important que vous soyez COHÉRENT lorsque vous utilisez nullet quand false. Je préfère utiliser nulllors de la récupération d' une valeur à partir d' une méthode, parce que je peux utiliser issetpour déterminer si une valeur est renvoyée au lieu d'utiliser emptyqui ne prendra pas en compte: false, 0, '0'ou une chaîne vide, ce qui peut être des valeurs viables dans de nombreuses situations. Pour moi, c'est la solution la plus propre dans une construction désordonnée.
JMRC

Réponses:

221

C'est spécifique au langage, mais en PHP:

Nullsignifie « rien ». Le var n'a pas été initialisé.

Falsesignifie " pas vrai dans un contexte booléen ". Utilisé pour montrer explicitement que vous traitez des problèmes logiques.

0est un int. Rien à voir avec le reste ci-dessus, utilisé pour les mathématiques.

Maintenant, ce qui est délicat, c'est que dans les langages dynamiques comme PHP, tous ont une valeur dans un contexte booléen , ce qui (en PHP) l'est False.

Si vous le testez avec ==, il teste la valeur booléenne, vous obtiendrez donc l'égalité. Si vous le testez avec ===, il testera le type et vous obtiendrez une inégalité.

Alors pourquoi sont-ils utiles?

Eh bien, regardez la strrpos()fonction. Il renvoie False s'il n'a rien trouvé, mais 0 s'il a trouvé quelque chose au début de la chaîne!

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

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

Et bien sûr, si vous traitez avec des états:

Vous voulez faire une différence entre DebugMode = False(réglé sur off), DebugMode = True(mis sur on) et DebugMode = Null(pas du tout défini, cela conduira à un débogage dur ;-)).

e-satis
la source
39
Remarque à propos de Null: PHP l'utilise comme "aucune valeur" mais ce n'est pas une bonne habitude à prendre. En général, Null signifie "valeur inconnue" qui est différente de "aucune valeur" ou "variable non initialisée". Rien plus 1 vaut 1, tandis qu'une valeur inconnue plus un est une valeur inconnue. N'oubliez pas que tout opérateur appliqué à null donnera (devrait) aboutir à null, car toute opération sur une "valeur inconnue" aboutit à une valeur inconnue.
Eli
7
gardez à l'esprit que ce sont toutes des intentions . rien à voir avec ce qui se passe dans la réalité. en réalité, une fonction peut renvoyer false pour des valeurs inexistantes (par exemple strpos, input_filter) et null en cas d'échec (par exemple input_filter). donc la réponse est, utilisez === false et / ou === null, après avoir lu la documentation de cette fonction particulière.
gcb
5
@Eli: d'où vient l'idée que Null signifie "valeur inconnue" en général. Je ne peux penser à aucun langage informatique où cela est vrai, ni cela ne veut dire qu'en anglais, du moins selon aucune définition que je puisse trouver ou avoir entendue. Vous savez peut-être quelque chose que je ne sais pas?
iconoclaste
2
@iconoclast - Je le prends du monde des bases de données. Si je comprends bien, null est utilisé comme espace réservé pour une valeur de données qui n'existe pas dans la base de données ou qui est inconnue. Voir dev.mysql.com/doc/refman/5.0/en/working-with-null.html ou en.wikipedia.org/wiki/Null_%28SQL%29 .
Eli
2
Eli n'a pas tort. Il déclare que sémantiquement, lorsque vous utilisez null, vous signalez aux autres programmeurs que vous ne savez pas ce qu'il y a dedans. C'est indéfini. Alors que lorsque vous utilisez 0, vous signalez que vous savez ce qu'il y a dedans: un nombre. Et ici, le nombre représente l'absence de choses. N'oubliez pas que peu importe comment les menaces PHP valorisent, les valeurs ont un sens, les valeurs sont une forme de documentation.
e-satis
45

nullest null. falseest false. Triste mais vrai.

il n'y a pas beaucoup de cohérence en PHP. les développeurs ESSAYEZ de rendre nul signifie «inconnu» ou «inexistant». mais souvent False servira de 'inexistant' (par exemple strrpos ('fail', 'search') renverra faux, et non nul)

vous verrez souvent null utilisé lorsqu'ils utilisent déjà false pour quelque chose. par exemple, filter_input (). Ils renvoient false si la variable échoue le filtre. et null si la variable n'existe pas (n'existe pas signifie qu'il a également échoué le filtre? alors pourquoi même retourner null?!?)

php a la commodité de renvoyer des données dans les fonctions. et souvent les développeurs entassent toutes sortes d'état d'échec au lieu des données.

Et il n'y a pas de moyen sensé en PHP de détecter les données (int, str, etc.) en cas d'échec (false, null)

vous devez à peu près toujours tester pour === null ou === false, selon la fonction. ou pour les deux, dans des cas tels que filter_input () / filter_var ()

et voici du plaisir avec la jonglerie de type. sans même inclure les tableaux et les objets.

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
la source
24
dans mon opionion 0 == null est un non-sens absolu, puisque 0 est une valeur et null est un drapeau qui montre que la variable n'est pas initialisée. Merci l'équipe php
mercsen
1
Vous avez répété deux fois votre section de code en commençant par var_dump( null == 0 );.
Sparky
2
ce qui est vraiment bizarre en php: null <-1 => TRUE
thehpi
1
@mercsen Au moins, si PHP se comportait systématiquement comme 0 == null, j'aurais été d'accord avec ça. Curieusement, 0 == nullet null == [], mais [] != 0!!
nawfal
1
strrpos('fail', 'search') will return false, and not nullà mon avis, c'est correct - si cela nullsignifie inconnu, le strrposretour nullserait comme s'il disait «Je ne sais pas si la chaîne est là» plutôt que «La chaîne n'est pas là».
Eborbob
22

Voici un exemple:

            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

Veuillez consulter ceci pour plus de références sur les comparaisons de types en PHP. Cela devrait vous donner une compréhension claire.

KristCont
la source
5

En PHP, vous pouvez utiliser les opérateurs === et! == pour vérifier non seulement si les valeurs sont égales mais aussi si leurs types correspondent. Ainsi par exemple: 0 == falseest true, mais 0 === falseest false. Il en va de même pour le !=versus !==. Aussi au cas où vous comparerieznull aux deux autres en utilisant les opérateurs mentionnés, attendez-vous à des résultats similaires.

Maintenant, en PHP, cette qualité de valeurs est généralement utilisée lors du retour d'une valeur qui peut parfois être 0(zéro), mais parfois il se peut que la fonction ait échoué. Dans de tels cas en PHP, vous revenez falseet vous devez vérifier ces cas en utilisant l'opérateur d'identité ===. Par exemple, si vous recherchez une position d'une chaîne dans l'autre et que vous utilisez strpos(), cette fonction renverra la position numérique qui peut être 0 si la chaîne est trouvée au tout début, mais si la chaîne ne se trouve pas à tout, puis strpos()reviendra falseet vous devez en tenir compte lors du traitement du résultat.

Si vous utilisez la même technique dans vos fonctions, toute personne familière avec la bibliothèque PHP standard comprendra ce qui se passe et comment vérifier si la valeur renvoyée correspond à ce qui est souhaité ou si une erreur s'est produite lors du traitement. Il en va de même pour les paramètres de fonction, vous pouvez les traiter différemment selon qu'il s'agit de tableaux ou de chaînes ou autre, et cette technique est également largement utilisée dans PHP, donc tout le monde l'obtiendra assez facilement. Alors je suppose que c'est le pouvoir.

inkredibl
la source
5

False, Null, Nothing, 0, Undefined , etc., etc.

Chacun de ceux-ci a des significations spécifiques qui correspondent aux concepts réels. Parfois, plusieurs significations sont surchargées en un seul mot-clé ou valeur.

En C et C ++ , NULL, Falseet 0sont surchargés à la même valeur. En C #, ce sont 3 concepts distincts.

nullou NULLindique généralement un manque de valeur, mais ne précise généralement pas pourquoi. 0indique le nombre naturel zéro et a une équivalence de type à 1, 2, 3, etc. et dans les langues qui prennent en charge des concepts séparés de NULLdevrait être traité uniquement un nombre.

Faux indique la non-vérité. Et il est utilisé dans les valeurs binaires . Cela ne veut pas dire non réglé, ni ne veut dire 0. Il indique simplement l'une des deux valeurs binaires.

Rien ne peut indiquer que la valeur est spécifiquement définie pour être rien, ce qui indique la même chose que null, mais avec intention.

Indéfini dans certaines langues indique que la valeur n'a pas encore été définie car aucun code n'a spécifié de valeur réelle.

Orion Adrian
la source
Intéressant, peut-être, mais ne parle pas du tout de PHP.
Brad
4

Je viens perdu 1/2 journée à essayer d'obtenir soit un 0, null, falserevenir destrops !

Voici tout ce que j'essayais de faire, avant de constater que la logique ne coulait pas dans la bonne direction, semblant qu'il y avait un trou noir dans le codage php:

Concept prend un nom de domaine hébergé sur un serveur, et assurez-vous qu'il n'est pas au niveau racine, OK plusieurs façons différentes de le faire, mais j'ai choisi différent en raison d'autres fonctions / constructions php que j'ai faites.

Quoi qu'il en soit, voici la base du 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"; 
    }
}

FINALEMENT après avoir lu ce sujet, j'ai trouvé que cela fonctionnait !!!

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

Merci pour cet article, je comprends maintenant que même si c'est Noël, ce n'est peut-être pas Noël car cela falsepeut aussi être unNULL jour!

Après avoir perdu une journée à déboguer un code simple, j'aurais aimé le savoir auparavant, car j'aurais pu identifier le problème, plutôt que d'aller partout pour essayer de le faire fonctionner. Il n'a pas fonctionné, comme False, NULLet 0ne sont pas tous les mêmes que True or False or NULL?

madesignUK
la source
2

Depuis la documentation en ligne PHP :

Pour convertir explicitement une valeur en booléen, utilisez les casts (booléen) ou (boolean).
Cependant, dans la plupart des cas, la conversion n'est pas nécessaire, car une valeur sera automatiquement convertie si un opérateur, une fonction ou une structure de contrôle nécessite un argument booléen.
Lors de la conversion en booléen, les valeurs suivantes sont considérées comme FAUX:

  • le booléen FALSElui-même
  • l'entier `` 0 (zéro)
  • le flotteur 0.0(zéro)
  • la chaîne vide et la chaîne "0"
  • un tableau avec zéro élément
  • un objet avec zéro variable membre (PHP 4 uniquement)
  • le type spécial NULL(y compris les variables non définies)
  • Objets SimpleXML créés à partir de balises vides
    Toute autre valeur est prise en compte TRUE(y compris toute ressource).

Donc, dans la plupart des cas, c'est la même chose.

En revanche, le ===et le ==ne sont pas la même chose. Régulièrement, vous n'avez besoin que de l'opérateur "égal". Clarifier:

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

Pour plus d'informations, consultez la page " Opérateurs de comparaison " dans la documentation en ligne PHP.

J'espère que cela t'aides.

Javier Constanzo
la source
1

Les différences entre ces valeurs se résument toujours à des règles détaillées spécifiques à la langue. Ce que vous apprenez pour PHP n'est pas nécessairement vrai pour Python, ou Perl, ou C, etc. Bien qu'il soit utile d'apprendre les règles du ou des langages avec lesquels vous travaillez, trop compter sur eux pose des problèmes . Le problème survient lorsque le prochain programmeur a besoin de maintenir votre code et que vous avez utilisé une construction qui tire parti de quelques petits détails de Null vs False (par exemple). Votre code doit avoir l'air correct (et inversement, un code erroné doit être incorrect ).

Greg Hewgill
la source
1

Null est utilisé dans les bases de données pour représenter «aucun enregistrement» ou «aucune information». Donc, vous pourriez avoir un petit champ qui décrit "cet utilisateur veut-il recevoir des e-mails par nous?", Où True signifie qu'il le fait, False signifie qu'il ne veut rien recevoir, mais Null signifie que vous ne le faites pas t sais. Ils peuvent provenir de jointures externes et autres.

Les implications logiques de Null sont souvent différentes - dans certaines langues, NULL n'est égal à rien, donc if (a == NULL) sera toujours faux.

Donc personnellement, je initialiserais toujours un booléen à FALSE, et en initialiser un à NULL aurait l'air un peu dégoûtant (même en C où les deux ne valent que 0 ... juste une chose de style).

Peter
la source
1

Je pense que les mauvais développeurs trouvent toutes les utilisations différentes de null / 0 / false dans leur code.

Par exemple, l'une des erreurs les plus courantes commises par les développeurs est de renvoyer un code d'erreur sous la forme de données avec une fonction.

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

Ceci est un exemple d'interface sucre. Ceci est expliqué dans le livre "Debuging the software development process" et aussi dans un autre livre "writing correct code".

Le problème avec ceci, c'est l'implication ou les hypothèses faites sur le type char. Sur certains compilateurs, le type char peut être non signé. Ainsi, même si vous retournez un -1, le compilateur peut renvoyer 1 à la place. Ces types d'hypothèses de compilateur en C ++ ou C sont difficiles à repérer.

Au lieu de cela, le meilleur moyen est de ne pas mélanger le code d'erreur avec vos données. Donc la fonction suivante.

char GetChar()

devient maintenant

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

Cela signifie que peu importe le niveau de jeunesse du développeur dans votre atelier de développement, il ne se trompera jamais. Bien que cela ne parle pas de redondance ou de dépendances dans le code.

Donc, en général, échanger bool comme premier type de classe dans la langue est acceptable et je pense que Joel en a parlé avec son récent postcast. Mais essayez de ne pas utiliser de mix and match bools avec vos données dans vos routines et tout devrait être parfait.

Tchad
la source
1

En PHP, cela dépend de la validation des types:

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

Techniquement nul n'est 0x00mais en PHP( null == 0x00 ) && ( null !== 0x00 ) .

0 est une valeur entière.

Gavin M. Roy
la source
1

Un fait intéressant à propos NULLde PHP: si vous définissez une variable égale à NULL, c'est la même chose que si vous l'aviez appelée unset().

NULLsignifie essentiellement qu'une variable n'a aucune valeur qui lui est assignée; falseest une valeur booléenne valide, 0est une valeur entière valide et PHP a des conversions assez laid entre 0, "0", ""et false.

dirtside
la source
0

Null n'est rien, False est un peu et 0 est (probablement) 32 bits.

Pas un expert PHP, mais dans certains des langages les plus modernes, ceux-ci ne sont pas interchangeables. Cela me manque un peu que 0 et false soient interchangeables, mais avec booléen étant un type réel, vous pouvez avoir des méthodes et des objets associés, ce n'est donc qu'un compromis. Null est nul cependant, l'absence de quoi que ce soit essentiellement.

CodeRedick
la source
0

Eh bien, je ne me souviens pas assez de mes jours PHP pour répondre à la partie "===", mais pour la plupart des langages de style C, NULL doit être utilisé dans le contexte des valeurs de pointeur, false comme booléen et zéro comme valeur numérique telle qu'un int. «\ 0» est la valeur habituelle d'un contexte de caractère. Je préfère généralement utiliser 0,0 pour les flotteurs et les doubles.

Alors ... la réponse rapide est: le contexte.

jasonmray
la source
0

Dans presque tous les langages modernes, null fait référence logiquement à des pointeurs (ou références) n'ayant pas de valeur, ou à une variable qui n'est pas initialisée. 0 est la valeur entière de zéro et false est la valeur booléenne de, eh bien, false. Pour compliquer les choses, en C, par exemple, nul, 0 et faux sont tous représentés exactement de la même manière. Je ne sais pas comment cela fonctionne en PHP.

Ensuite, pour compliquer davantage les choses, les bases de données ont un concept de null, ce qui signifie manquant ou non applicable, et la plupart des langages n'ont pas de moyen direct de mapper un DBNull à leur null. Jusqu'à récemment, par exemple, il n'y avait aucune distinction entre un int étant nul et nul, mais cela a été changé avec des entiers Nullable.

Désolé de rendre cela compliqué. C'est juste que cela a été un point de friction difficile dans les langues pendant des années, et jusqu'à récemment, il n'y avait aucune résolution claire nulle part. Les gens avaient l'habitude de simplement regrouper les éléments ou de rendre vide ou 0 représentant des valeurs nulles dans la base de données, ce qui ne fonctionne pas toujours très bien.

Charles Graham
la source
0

Faux et 0 sont conceptuellement similaires, c'est-à-dire qu'ils sont isomorphes. 0 est la valeur initiale de l'algèbre des nombres naturels et False est la valeur initiale de l'algèbre booléenne.

En d'autres termes, 0 peut être défini comme le nombre qui, lorsqu'il est ajouté à un nombre naturel, donne le même nombre:

x + 0 = x

De même, False est une valeur telle qu'une disjonction de celle-ci et de toute autre valeur est la même valeur:

x || False = x

Null est conceptuellement quelque chose de totalement différent. Selon le langage, il existe différentes sémantiques, mais aucune d'elles ne décrit une «valeur initiale» comme False et 0 le sont. Il n'y a pas d'algèbre pour Null. Il concerne les variables, généralement pour indiquer que la variable n'a pas de valeur spécifique dans le contexte actuel. Dans la plupart des langages, aucune opération n'est définie sur Null et c'est une erreur d'utiliser Null comme opérande. Dans certains langages, il existe une valeur spéciale appelée "bottom" plutôt que "null", qui est un espace réservé pour la valeur d'un calcul qui ne se termine pas.

J'ai écrit plus en détail sur les implications de NULL ailleurs.

Apocalisp
la source
1
offtopic, false == 0 est complètement retardé. Encore plus avec php renvoyant des données OU échec dans une fonction. voir le retour de mysql_insert_id. "" "L'ID généré pour une colonne AUTO_INCREMENT par la requête précédente en cas de succès, 0 si la requête précédente ne génère pas de valeur AUTO_INCREMENT, ou FALSE si aucune connexion MySQL n'a été établie." "" En gros, il peut renvoyer A) l'id, B) zéro, C) faux ... maintenant si c'est le 1er élément du tableau, id sera zéro! donc les trois valeurs sont les mêmes! comment le développeur peut-il comprendre trois types de zéros? ... et je suis d'accord avec votre message sur null.
gcb
0

Quelqu'un peut m'expliquer pourquoi «NULL» n'est pas simplement une chaîne dans une instance de comparaison?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!
Vladzur
la source
1
Parce que PHP convertit en interne le type entier et compare ensuite. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)voir php.net/manual/en/language.operators.comparison.php Traduire des chaînes et des ressources en nombres, mathématiques habituelles
Sevyls
-1

Les problèmes de fausseté proviennent de l'historique PHP. Le problème cible le type scalaire mal défini.

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

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

La rigueur de PHP7 est un pas en avant, mais peut-être pas suffisant. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

Adrian
la source