Nulo vs. Falso vs. 0 no PHP

146

Disseram-me que bons desenvolvedores podem local / utilizar a diferença entre Nulle Falsee 0e todos os outros bons entidades "nada".
Qual é a diferença, especificamente em PHP? Tem algo a ver com isso ===?

stalepretzel
fonte
É quase impossível realmente descobrir quando o que é usado. Eu acho que é importante que você seja consistente quando usar nulle quando false. Eu prefiro usar nullao recuperar um valor de um método, porque eu posso usar issetpara determinar se um valor é devolvido em vez de usar emptyque não vai levar em conta: false, 0, '0'ou uma cadeia vazia, que pode ser valores viáveis em muitas situações. Para mim, é a solução mais limpa em uma construção confusa.
JMRC 11/02

Respostas:

221

É específico da linguagem, mas em PHP:

Nullsignifica " nada ". O var não foi inicializado.

Falsesignifica " não é verdade em um contexto booleano ". Usado para mostrar explicitamente que você está lidando com problemas lógicos.

0é um int. Nada a ver com o resto acima, usado para matemática.

Agora, o que é complicado, é que em linguagens dinâmicas como PHP, todas elas têm um valor em um contexto booleano , o que (em PHP) é False.

Se você testá-lo ==, ele está testando o valor booleano, para obter igualdade. Se você testá-lo ===, ele testará o tipo e você obterá desigualdade.

Então, por que eles são úteis?

Bem, olhe para a strrpos()função. Retorna False se não encontrou nada, mas 0 se encontrou algo no início da string!

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

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

E, claro, se você lida com estados:

Você quer fazer a diferença entre DebugMode = False(definido como desativado), DebugMode = True(ativado) e DebugMode = Null(não definido de forma alguma, levará à depuração forçada ;-)).

e-satis
fonte
39
Nota sobre Nulo: O PHP o usa como "sem valor", mas esse não é um bom hábito. Em geral, Nulo significa "valor desconhecido", que é diferente de "sem valor" ou "variável não inicializada". Nada mais 1 é 1, enquanto um valor desconhecido mais um é um valor desconhecido. Lembre-se de que qualquer operador aplicado a nulo resultará em nulo, porque qualquer operação em um "valor desconhecido" resulta em um valor desconhecido.
Eli
7
tenha em mente que todas essas são intenções . nada a ver com o que acontece na realidade. na realidade, uma função pode retornar falso para valores inexistentes (por exemplo, strpos, input_filter) e nulo para falha (por exemplo, input_filter). portanto, a resposta é: use === false e / ou === null, depois de ler a documentação específica da função.
gcb
5
@ Eli: de onde você tira a ideia de que Nulo significa "valor desconhecido" em geral. Não consigo pensar em nenhuma linguagem de computador onde isso seja verdade, nem significa que, em inglês, pelo menos não de acordo com qualquer definição que eu possa encontrar ou ter ouvido. Talvez você saiba algo que eu não sei?
Iconoclast
2
@iconoclast - Estou tirando isso do mundo dos bancos de dados. Pelo que entendi, null é usado como um espaço reservado para um valor de dados que não existe no banco de dados ou é desconhecido. Consulte dev.mysql.com/doc/refman/5.0/en/working-with-null.html ou en.wikipedia.org/wiki/Null_%28SQL%29 .
Eli
2
Eli não está errado. Ele está afirmando que, semanticamente, quando você usa nulo, você sinaliza para outros programadores que você não sabe o que está lá. É indefinido. Enquanto você usa 0, sinaliza que sabe o que há lá: um número. E aqui o número representa a ausência de coisas. Lembre-se de que, independentemente de como o PHP ameace valores, os valores têm um significado, os valores são uma forma de documentação.
e-satis
45

nullé null. falseé false. Triste mas verdadeiro.

não há muita consistência no PHP. os desenvolvedores tentam tornar nulo significa "desconhecido" ou "inexistente". mas frequentemente False servirá como 'inexistente' (por exemplo, strrpos ('fail', 'search') retornará falso, e não nulo)

você verá frequentemente nulo sendo usado quando eles já estão usando false para alguma coisa. por exemplo, filter_input (). Eles retornam false se a variável falhar no filtro. e null se a variável não existir (não existir significa que também falhou no filtro? então, por que retornar nulo?!?)

O php tem a conveniência de retornar dados nas funções. e ofterter os desenvolvedores em todos os tipos de status de falha, em vez dos dados.

E não há nenhuma maneira sã no PHP para detectar dados (int, str, etc) de falhas (falso, nulo)

você praticamente sempre deve testar === null ou === false, dependendo da função. ou para ambos, em casos como filter_input () / filter_var ()

e aqui está um pouco divertido com o malabarismo de tipos. nem mesmo incluindo matrizes e 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
fonte
24
na minha opinião, 0 == null é um absurdo absoluto, já que 0 é um valor e null é um sinalizador que mostra que a variável não foi inicializada. Obrigado equipe php
mercsen
1
Você repetiu duas vezes sua seção de código começando com var_dump( null == 0 );.
Sparky
2
o que é realmente estranho em php: null <-1 => true
thehpi
1
@mercsen No mínimo, se o PHP se comportasse consistentemente como 0 == null, eu estaria bem com isso. Estranhamente, 0 == nulle null == [], mas [] != 0!!
Nawfal 14/11/2015
1
strrpos('fail', 'search') will return false, and not nullna minha opinião, está correto - se nullmeios desconhecidos, strrposretornar nullseria como 'Não sei se a cadeia está lá' em vez de 'A cadeia não está lá'.
Eborbob
22

Abaixo está um exemplo:

            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

Por favor, veja isto para mais referência de comparações de tipos no PHP. Isso deve lhe dar uma compreensão clara.

KristCont
fonte
5

No PHP, você pode usar os operadores === e! == para verificar não apenas se os valores são iguais, mas também se os tipos correspondentes. Então, por exemplo: 0 == falseé true, mas 0 === falseé false. O mesmo vale para !=versus !==. Também no caso de você comparar nullcom os outros dois usando os operadores mencionados, espere resultados semelhantes.

Agora, no PHP, essa qualidade de valores geralmente é usada ao retornar um valor que às vezes pode ser 0(zero), mas às vezes pode ser que a função falhe. Nesses casos, no PHP, você retorna falsee precisa verificar esses casos usando o operador de identidade ===. Por exemplo, se você estiver procurando por uma posição de uma string dentro da outra e estiver usando strpos(), essa função retornará a posição numérica que pode ser 0 se a string for encontrada no início, mas se a string não for encontrada em tudo strpos()retornará falsee você deverá levar isso em consideração ao lidar com o resultado.

Se você usar a mesma técnica em suas funções, qualquer pessoa familiarizada com a biblioteca PHP padrão entenderá o que está acontecendo e como verificar se o valor retornado é o desejado ou se ocorreu algum erro durante o processamento. O mesmo vale para os parâmetros de função; você pode processá-los de maneira diferente, dependendo de serem matrizes ou seqüências de caracteres ou não, e essa técnica também é muito usada em todo o PHP, para que todos os entendam facilmente. Então acho que esse é o poder.

inkredibl
fonte
5

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

Cada um deles tem significados específicos que se correlacionam com os conceitos reais. Às vezes, vários significados são sobrecarregados em uma única palavra-chave ou valor.

Em C e C ++ , NULL, Falsee 0estão sobrecarregados com o mesmo valor. Em C # , são três conceitos distintos.

nullou NULLgeralmente indica falta de valor, mas geralmente não especifica o porquê. 0indica o número natural zero e tem equivalência de tipo 1, 2, 3 etc. , e em idiomas que suportam conceitos separados de NULLdeve ser tratado apenas um número.

False indica não-verdade. E é usado em valores binários . Não significa desabilitado, nem significa 0. Simplesmente indica um dos dois valores binários.

Nada pode indicar que o valor está definido especificamente para ser nada que indica a mesma coisa que nulo, mas com intenção.

Indefinido em alguns idiomas indica que o valor ainda não foi definido porque nenhum código especificou um valor real.

Orion Adrian
fonte
Interessante, talvez, mas não discute nada sobre PHP.
25412 Brad
4

Acabo desperdiçado um dia 1/2 tentando obter qualquer um 0, null, falsepara retornar a partir strops!

Aqui está tudo o que eu estava tentando fazer, antes de descobrir que a lógica não estava fluindo na direção certa, parecendo que havia um buraco negro na codificação php:

O conceito leva um nome de domínio hospedado em um servidor e certifique-se de que não esteja no nível da raiz. OK, várias maneiras diferentes de fazer isso, mas eu escolhi diferente devido a outras funções / construções php que fiz.

Enfim, aqui estava a base do 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, depois de ler este tópico, achei que funcionou !!!

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

Obrigado por este artigo, agora entendo que, embora seja Natal, pode não ser Natal false, pois também pode ser um NULLdia!

Depois de desperdiçar um dia depurando algum código simples, gostaria de saber isso antes, pois seria capaz de identificar o problema, em vez de percorrer todo o lugar tentando fazê-lo funcionar. Não funcionou, como False, NULLe 0não são todos iguais True or False or NULL?

madesignUK
fonte
2

Na documentação online do PHP :

Para converter explicitamente um valor em booleano, use as conversões (bool) ou (boolean).
No entanto, na maioria dos casos, a conversão é desnecessária, pois um valor será convertido automaticamente se um operador, função ou estrutura de controle exigir um argumento booleano.
Ao converter para booleano, os seguintes valores são considerados FALSE:

  • o FALSEpróprio booleano
  • o número inteiro `` 0 (zero)
  • o flutuador 0.0(zero)
  • a sequência vazia e a sequência "0"
  • uma matriz com zero elementos
  • um objeto com zero variáveis ​​de membro (somente PHP 4)
  • o tipo especial NULL(incluindo variáveis ​​não definidas)
  • Objetos SimpleXML criados a partir de tags vazias
    Todos os outros valores são considerados TRUE(incluindo qualquer recurso).

Então, na maioria dos casos, é o mesmo.

Por outro lado, o ===e o ==não são a mesma coisa. Normalmente, você só precisa do operador "igual". Esclarecer:

$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 obter mais informações, consulte a página " Operadores de comparação " nos documentos online do PHP.

Espero que isto ajude.

Javier Constanzo
fonte
1

As diferenças entre esses valores sempre se resumem a regras específicas de idioma. O que você aprende para PHP não é necessariamente verdadeiro para Python, Perl ou C, etc. Embora seja valioso aprender as regras para o (s) idioma (s) com o qual você está trabalhando, depender demais deles é pedir problemas. . O problema ocorre quando o próximo programador precisa manter seu código e você usou alguma construção que tira proveito de alguns pequenos detalhes de Nulo vs. Falso (por exemplo). Seu código deve parecer correto (e, inversamente, o código errado deve parecer errado ).

Greg Hewgill
fonte
1

Nulo é usado nos bancos de dados para representar "sem registro" ou "sem informação". Portanto, você pode ter um campo de bits que descreva "esse usuário deseja receber e-mails por nós", onde True significa que deseja, False significa que não deseja receber nada, mas Null significa que você não não sei. Eles podem surgir através de junções externas e afins.

As implicações lógicas do Null geralmente são diferentes - em alguns idiomas NULL não é igual a nada, portanto, se (a == NULL) sempre será falso.

Então, pessoalmente, eu sempre inicializaria um booleano para FALSE, e inicializar um para NULL ficaria um pouco nojento (mesmo em C, onde os dois são apenas 0 ... apenas uma coisa de estilo).

Peter
fonte
1

Acho que os desenvolvedores ruins encontram todos os usos diferentes de null / 0 / false no código.

Por exemplo, um dos erros mais comuns que os desenvolvedores cometem é retornar o código de erro na forma de dados com uma função.

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

Este é um exemplo de uma interface de açúcar. Isso é explicado no livro "Depurando o processo de desenvolvimento de software" e também em outro livro "escrevendo o código correto".

O problema disso é a implicação ou suposições feitas no tipo de caractere. Em alguns compiladores, o tipo de caractere pode não ser assinado. Portanto, mesmo que você retorne -1, o compilador pode retornar 1. Esses tipos de suposições do compilador em C ++ ou C são difíceis de detectar.

Em vez disso, a melhor maneira é não misturar código de erro com seus dados. Então, a seguinte função.

char GetChar()

agora se torna

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

Isso significa que não importa quão jovem o desenvolvedor seja em sua loja de desenvolvimento, ele ou ela nunca entenderão isso errado. Embora isso não esteja falando de redudância ou dependência de código.

Então, em geral, trocar bool como o tipo de primeira classe no idioma é bom e acho que joel falou sobre isso com seu recente postcast. Mas tente não usar misturar e combinar bools com seus dados em suas rotinas e você deve estar perfeitamente bem.

Chade
fonte
1

No PHP, depende se você está validando tipos:

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

Tecnicamente nulo, 0x00mas está em PHP ( null == 0x00 ) && ( null !== 0x00 ).

0 é um valor inteiro.

Gavin M. Roy
fonte
1

Um fato interessante sobre o NULLPHP: se você definir um var igual a NULL, é o mesmo que se você o tivesse chamado unset().

NULLessencialmente significa que uma variável não tem valor atribuído a ela; falseé um valor booleano válido, 0é um valor inteiro válido, e PHP tem algumas conversões bastante feias entre 0, "0", "", e false.

dirtside
fonte
0

Nulo não é nada, Falso é um pouco e 0 é (provavelmente) 32 bits.

Não é um especialista em PHP, mas em algumas das linguagens mais modernas essas não são intercambiáveis. Eu meio que sinto falta de 0 e falso ser intercambiável, mas como booleano é um tipo real, você pode ter métodos e objetos associados a ele, então isso é apenas uma troca. Nulo é nulo, a ausência de qualquer coisa essencialmente.

CodeRedick
fonte
0

Bem, não me lembro o suficiente dos meus dias em PHP para responder à parte "===", mas para a maioria das linguagens de estilo C, NULL deve ser usado no contexto de valores de ponteiro, falso como um booleano e zero como um valor numérico como int. '\ 0' é o valor habitual para um contexto de caractere. Normalmente, também prefiro usar 0,0 para carros alegóricos e duplos.

Então .. a resposta rápida é: contexto.

jasonmray
fonte
0

Em praticamente todas as linguagens modernas, null refere-se logicamente a ponteiros (ou referências) que não possuem um valor ou uma variável que não é inicializada. 0 é o valor inteiro zero e false é o valor booleano de, bem, false. Para complicar as coisas, em C, por exemplo, nulo, 0 e falso são todos representados exatamente da mesma maneira. Eu não sei como isso funciona em PHP.

Então, para complicar ainda mais, os bancos de dados têm um conceito de nulo, o que significa ausente ou não aplicável, e a maioria dos idiomas não tem uma maneira direta de mapear um DBNull para seu nulo. Até recentemente, por exemplo, não havia distinção entre um int sendo nulo e sendo zero, mas isso foi alterado com ints anuláveis.

Desculpe fazer esse som complicado. É que esse tem sido um ponto difícil nos idiomas há anos e, até recentemente, não tinha nenhuma resolução clara em lugar algum. As pessoas costumavam agrupar as coisas ou deixar em branco ou 0 representam nulos no banco de dados, o que nem sempre funciona muito bem.

Charles Graham
fonte
0

Falso e 0 são conceitualmente semelhantes, ou seja, são isomórficos. 0 é o valor inicial para a álgebra de números naturais e Falso é o valor inicial para a álgebra booleana.

Em outras palavras, 0 pode ser definido como o número que, quando adicionado a algum número natural, produz esse mesmo número:

x + 0 = x

Da mesma forma, False é um valor tal que uma disjunção dele e qualquer outro valor é o mesmo valor:

x || False = x

Nulo é conceitualmente algo totalmente diferente. Dependendo do idioma, existem semânticas diferentes para ele, mas nenhuma delas descreve um "valor inicial" como Falso e 0. Não há álgebra para Nulo. Pertence a variáveis, geralmente para denotar que a variável não tem valor específico no contexto atual. Na maioria dos idiomas, não há operações definidas no Null, e é um erro usar o Null como um operando. Em alguns idiomas, existe um valor especial chamado "bottom" em vez de "null", que é um espaço reservado para o valor de uma computação que não termina.

Eu escrevi mais amplamente sobre as implicações do NULL em outros lugares.

Apocalisp
fonte
1
offtopic, false == 0 é completamente retardado. Ainda mais com o php retornando dados OU falha em uma função. veja o retorno para mysql_insert_id. "" "O ID gerado para uma coluna AUTO_INCREMENT pela consulta anterior com êxito, 0 se a consulta anterior não gerar um valor AUTO_INCREMENT, ou FALSE se nenhuma conexão MySQL foi estabelecida." "" Basicamente, ele pode retornar A) o ID, B) zero, C) falso ... agora, se esse é o primeiro item da tabela, o ID será zero! então todos os três valores são iguais! como o desenvolvedor pode entender três tipos de zeros? ... e eu concordo com a sua postagem em null.
gcb
0

Alguém pode me explicar por que 'NULL' não é apenas uma string em uma instância de comparação?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!
vladzur
fonte
1
Porque o PHP lança internamente para o tipo inteiro e depois o compara. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)veja php.net/manual/en/language.operators.comparison.php Traduzir cordas e recursos para números, matemática de costume
Sevyls
-1

Os problemas com falsidade vêm da história do PHP. O problema tem como alvo o tipo escalar não bem definido.

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

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

O rigor do PHP7 é um passo à frente, mas talvez não seja suficiente. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

adrian
fonte