Analisando uma string em um valor booleano no PHP

126

Hoje eu estava brincando com o PHP e descobri que os valores da string "true" e "false" não são analisados ​​corretamente como booleanos em uma condição, por exemplo, considerando a seguinte função:

function isBoolean($value) {
   if ($value) {
      return true;
   } else {
      return false;
   }
}

Se eu executar:

isBoolean("true") // Returns true
isBoolean("") // Returns false
isBoolean("false") // Returns true, instead of false
isBoolean("asd") // Returns true, instead of false

Apenas parece funcionar com os valores "1" e "0":

isBoolean("1") // Returns true
isBoolean("0") // Returns false

Existe uma função nativa no PHP para analisar as seqüências de caracteres "true" e "false" em booleano?

Marca
fonte
No seu código, isBoolean("")deve retornar false.
BoltClock
Você deve alterar a resposta aceita para a resposta de Eric Caron. Ele mostra uma função nativa que faz o que você pede.
Code Commander
1
O PHP não pensa no que a string diz: "false" são apenas cinco caracteres que não significam nada. Porém, eles são algo ; portanto, o valor booleano é avaliado para trueo leitor humano, mesmo que pareça mais intuitivo FALSE.
zeel

Respostas:

413

Existe um método PHP nativo de fazer isso que usa o método filter_var do PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

De acordo com o manual do PHP :

Retorna TRUE para "1", "true", "on" e "yes". Retorna FALSE caso contrário.

Se FILTER_NULL_ON_FAILURE estiver definido, FALSE será retornado apenas para "0", "false", "off", "no" e "" e NULL será retornado para todos os valores não-booleanos.

Eric Caron
fonte
Essa deveria ter sido a resposta aceita. Funções embutidas em PHP são melhores do que criar suas próprias. Não há necessidade de reinventar a roda! Pena que era tarde demais: P
casraf 10/13/13
1
também diminui o valor da comparação?
Mobiletainment
3
@Mobiletainment, sim - ele lida com qualquer embalagem que você pode imaginar para $ value (false, FALSE, FALSE, etc.)
Eric Caron
Teste de Borked do meu lado. Utilizado == em vez de === para comparação. Removerá meu comentário anterior para não confundir as pessoas.
30615 andig
6
A resposta me pegou de surpresa porque você precisa adicionar a bandeira FILTER_NULL_ON_FAILUREà filter_var()função e NÃO substituí-la FILTER_VALIDATE_BOOLEANcomo eu pensava. Isso resultará no seguinte código, que fez o truque para mim:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54
14

O motivo é que todas as strings são avaliadas ao trueconvertê-las em booleanas, exceto "0"e"" (string vazia).

A função a seguir fará exatamente o que você deseja: se comporta exatamente como o PHP, mas também avalia a string "false"como false:

function isBoolean($value) {
   if ($value && strtolower($value) !== "false") {
      return true;
   } else {
      return false;
   }
}

A documentação explica que: http://php.net/manual/en/language.types.boolean.php :

Ao converter para booleano, os seguintes valores são considerados FALSE:

  • o próprio booleano FALSE
  • o número inteiro 0 (zero)
  • o flutuador 0,0 (zero)
  • a string vazia e a sequência "0"
  • uma matriz com zero elementos
  • o tipo especial NULL (incluindo variáveis ​​não definidas)
  • Objetos SimpleXML criados a partir de tags vazias

Qualquer outro valor é considerado VERDADEIRO (incluindo qualquer recurso).

Arnaud Le Blanc
fonte
2
+1 Nice. (Poderia lançar um strtolower lá, mas que é sobre ele.)
John Parker
Eu acho que middaparka significava comparar strtolower ($ value) com 'false'. Passar um literal 'false' para strtolower é um pouco ... estúpido? :)
Paul Dixon
@Paul Dixon Yup, é a isso que eu estava me referindo. :-)
John Parker
2
@Marco - if ($ value && strtolower ($ value)! == "faux") {se você estiver trabalhando em francês; if ($ value && strtolower ($ value)! == "falsch") {em alemão; if ($ value && strtolower ($ value)! == "onwaar") {em holandês ... você pode entender por que o PHP não tem isso embutido como padrão # #
Mark Baker
1
"todas as cadeias não vazias são avaliadas como verdadeiras quando convertidas para booleanas, exceto" 0 "."
BoltClock
5

Somente no PHP "0"ou a string vazia é coerente com false; todas as outras strings não vazias são coercitivas para true. Do manual :

Ao converter para booleano, os seguintes valores são considerados FALSE:

  • a sequência vazia e a sequência "0"

Você precisa escrever sua própria função para lidar com as cordas "true"vs "false". Aqui, suponho que todo o resto padrão seja false:

function isBoolean($value) {
   if ($value === "true") {
      return true;
   } else {
      return false;
   }
}

Em uma nota lateral que poderia ser facilmente condensada para

function isBoolean($value) {
   return $value === "true";
}
BoltClock
fonte
4

Recentemente, eu precisava de uma função de conversão booleana "solta" para lidar com strings como as que você está perguntando (entre outras coisas). Encontrei algumas abordagens diferentes e criei um grande conjunto de dados de teste para executá-las . Nada se encaixava perfeitamente nas minhas necessidades, então escrevi as minhas:

function loosely_cast_to_boolean($value) {
    if(is_array($value) || $value instanceof Countable) {
        return (boolean) count($value);
    } else if(is_string($value) || is_object($value) && method_exists($value, '__toString')) {
        $value = (string) $value;
        // see http://www.php.net/manual/en/filter.filters.validate.php#108218
        // see https://bugs.php.net/bug.php?id=49510
        $filtered = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        if(!is_null($filtered)) {
            return $filtered;
        } else {
            // "none" gets special treatment to be consistent with ini file behavior.
            // see documentation in php.ini for more information, in part it says: 
            // "An empty string can be denoted by simply not writing anything after 
            // the equal sign, or by using the None keyword".
            if(strtolower($value) === 'none') {
                $value = '';
            }
            return (boolean) $value;
        }
    } else {
        return (boolean) $value;
    }
}

Observe que, para objetos contáveis ​​e combináveis ​​por sequência, isso favorecerá a contagem sobre o valor da sequência para determinar a veracidade. Ou seja, se $object instanceof Countableisso retornar, (boolean) count($object)independentemente do valor de(string) $object .

Você pode ver o comportamento dos dados de teste que usei, bem como os resultados de várias outras funções aqui . É meio difícil analisar os resultados desse pequeno iframe, para que você possa visualizar a saída do script em uma página inteira (esse URL não é documentado, portanto isso pode não funcionar para sempre). Caso esses links morram algum dia, eu coloco o código em pastebin .

A linha entre o que "deveria ser verdade" e o que não deveria é bastante arbitrária; os dados que usei são classificados com base em minhas necessidades e preferências estéticas; as suas podem diferir.

Matt Kantor
fonte
Esta função funciona perfeitamente, obrigado! Mas seus links agora são 404. #
servermanfail
3

Estou usando essa construção para transformar cadeias de caracteres em booleanos, pois você deseja truea maioria dos outros valores:

$str = "true";
$bool = !in_array($str, array("false", "", "0", "no", "off"));
mario
fonte
1

Existe uma função no PHP para analisar as seqüências de caracteres "true" e "false" em booleano?

Não - ambos são strings, e os dois (como você diz) avaliam true. Somente cadeias vazias são avaliadas parafalse no PHP.

Você precisaria testar isso manualmente. Se possível, seria melhor trabalhar com valores booleanos "reais".

Pekka
fonte
1
Nem todas as strings são avaliadas trueem PHP.
precisa saber é o seguinte
1
Não estava corrigindo, apenas esclarecendo. Dizer "ambas são seqüências de caracteres [e avaliar para true]" pode dar a um novato a impressão errada, especialmente uma de outro idioma com regras de digitação mais rigorosas, em que uma string é uma string e o conteúdo não importa quando está sendo convertido em um booleano (como Rubi).
precisa saber é o seguinte
1
"Somente cadeias vazias são avaliadas como falsas no PHP." Mas e a string não vazia "0"? Isso também não avalia false?
Sepster 27/08/15
0

A maneira mais fácil de converter com segurança para um booleano;

    $flag = 'true';

    if( filter_var( $flag,FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) !== null) {
      $flag = filter_var($flag,FILTER_VALIDATE_BOOLEAN);
    }

    gettype($flag); // Would Return 'Boolean'
    echo 'Val: '.$flag; // Would Output 'Val: 1'
Timothy Perez
fonte
0

Se sua API aceitar apenas as strings "true" ou "false", com todo o resto se tornandonull , tente:

$boolean = ['true' => true, 'false' => false][$inputString] ?? null;

Isso pressupõe que $inputnão é um objeto. Null coalesce ( ??) foi introduzido no PHP 7.0.

Matt Janssen
fonte