Analisi di una stringa in un valore booleano in PHP


126

Oggi stavo giocando con PHP e ho scoperto che i valori di stringa "true" e "false" non sono analizzati correttamente in booleano in una condizione, ad esempio considerando la seguente funzione:

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

Se eseguo:

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

Sembra funzionare solo con i valori "1" e "0":

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

Esiste una funzione nativa in PHP per analizzare le stringhe "true" e "false" in booleane?


Nel tuo codice, isBoolean("")dovrebbe restituire false.
BoltClock

Dovresti considerare di cambiare la risposta accettata alla risposta di Eric Caron. Ti mostra una funzione nativa che fa quello che chiedi.
Codice comandante

1
PHP non pensa a cosa dice la stringa, "falso" è solo cinque caratteri che non significano nulla. Sono qualcosa però, quindi il valore booleano valuta trueanche se a un lettore umano, sembrerebbe più intuitivo che significasse FALSE.
zeel

Risposte:


413

Esiste un metodo PHP nativo per fare ciò che utilizza il metodo filter_var di PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

Secondo il manuale di PHP :

Restituisce VERO per "1", "vero", "attivo" e "sì". Restituisce FALSO in caso contrario.

Se FILTER_NULL_ON_FAILURE è impostato, FALSE viene restituito solo per "0", "false", "off", "no" e "" e NULL viene restituito per tutti i valori non booleani.


Questa avrebbe dovuto essere la risposta accettata. Le funzioni PHP integrate sono meglio che costruirne una tua. Non c'è bisogno di reinventare la ruota! Peccato che fosse troppo tardi: P
casraf il

1
mette in minuscolo anche il valore per il confronto?
Mobiletainment

3
@Mobiletainment, sì - gestisce qualsiasi involucro che puoi immaginare per $ value (false, FALSE, FalSe, ecc.)
Eric Caron,

Testcase borked dalla mia parte. Usato == invece di === per il confronto. Rimuoverò il mio commento precedente per non confondere le persone.
andig

6
La risposta mi ha colto di sorpresa perché devi aggiungere il flag FILTER_NULL_ON_FAILUREalla filter_var()funzione e NON sostituirlo con FILTER_VALIDATE_BOOLEANcome pensavo. Ciò comporterà il seguente codice che ha fatto il trucco per me:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54

14

Il motivo è che tutte le stringhe valutano truequando le converte in booleane, tranne "0"e ""(stringa vuota).

La seguente funzione farà esattamente quello che vuoi: si comporta esattamente come PHP, ma valuta anche la stringa "false"come false:

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

La documentazione spiega che: http://php.net/manual/en/language.types.boolean.php :

Quando si converte in booleano, i seguenti valori sono considerati FALSI:

  • lo stesso FALSO booleano
  • l'intero 0 (zero)
  • il galleggiante 0.0 (zero)
  • la stringa vuota e la stringa "0"
  • un array con zero elementi
  • il tipo speciale NULL (comprese le variabili non impostate)
  • Oggetti SimpleXML creati da tag vuoti

Ogni altro valore è considerato VERO (compresa qualsiasi risorsa).


2
+1 Nizza. (Potrebbe lanciare un potere, ma questo è tutto.)
John Parker,

Penso che middaparka abbia significato confrontare strtolower ($ value) con "false". Passare un "falso" letterale in strtolower è un po '.... stupido? :)
Paul Dixon,

@Paul Dixon Yup, questo è ciò a cui mi riferivo. :-)
John Parker,

2
@Marco - if ($ value && strtolower ($ value)! == "faux") {se lavori in francese; if ($ value && strtolower ($ value)! == "falsch") {in tedesco; if ($ value && strtolower ($ value)! == "onwaar") {in olandese ... puoi capire perché PHP non lo ha incorporato come standard
Mark Baker

1
"tutte le stringhe non vuote vengono valutate come vere quando vengono convertite in booleane, tranne" 0 "."
BoltClock

5

Solo in PHP "0"o la stringa vuota viene forzata su false; ogni altra stringa non vuota viene forzata su true. Dal manuale :

Quando si converte in booleano, vengono considerati i seguenti valori FALSE:

  • la stringa vuota e la stringa "0"

Hai bisogno di scrivere la propria funzione per gestire le stringhe "true"vs "false". Qui, presumo che tutte le altre impostazioni predefinite siano false:

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

Su una nota a margine che potrebbe essere facilmente condensata

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

4

Di recente avevo bisogno di una funzione di conversione booleana "libera" per gestire stringhe come quelle di cui stai chiedendo (tra le altre cose). Ho trovato alcuni approcci diversi e ho trovato una grande serie di dati di test per eseguirli . Niente di adatto alle mie esigenze, quindi ho scritto le mie:

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;
    }
}

Si noti che per gli oggetti che possono essere numerati e calcolabili tramite stringa, ciò favorirà il conteggio rispetto al valore di stringa per determinare la verità. Cioè, se $object instanceof Countablequesto restituirà (boolean) count($object)indipendentemente dal valore di(string) $object .

Puoi vedere il comportamento per i dati di test che ho usato così come i risultati per diverse altre funzioni qui . È un po 'difficile sfogliare i risultati da quel piccolo iframe, quindi puoi visualizzare l'output dello script in una pagina intera , invece (quell'URL non è documentato, quindi potrebbe non funzionare per sempre). Nel caso in cui quei collegamenti muoiano un giorno, ho inserito anche il codice su pastebin .

Il confine tra ciò che "dovrebbe essere vero" e ciò che non dovrebbe essere è piuttosto arbitrario; i dati che ho usato sono classificati in base alle mie esigenze e preferenze estetiche, i tuoi potrebbero essere diversi.


Questa funzione funziona perfettamente, grazie! Ma i tuoi collegamenti ora sono 404.
servermanfail

3

Sto usando questo costrutto per trasformare le stringhe in booleane, dal momento che vuoi trueper la maggior parte degli altri valori:

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

1

Esiste una funzione in PHP per analizzare le stringhe "true" e "false" in booleane?

No - entrambi sono stringhe e entrambi (come dici tu) valutano true. Solo le stringhe vuote vengono valutate falsein PHP.

Dovresti testarlo manualmente. Se possibile, tuttavia, sarebbe meglio lavorare con valori booleani "reali".


1
Non tutte le stringhe vengono valutate truein PHP.
coreyward

1
Non correggevo, stavo solo chiarendo. Dire "entrambi sono stringhe [e valutare per true]" potrebbe dare a un neofita un'impressione sbagliata, in particolare uno da un'altra lingua con regole di battitura più rigide in cui una stringa è una stringa e il contenuto non importa quando viene convertito in un valore booleano (come Rubino).
coreyward

1
"Solo le stringhe vuote vengono valutate come false in PHP." Ma per quanto riguarda la stringa non vuota "0"? Anche questo non valuta false?
Sepster,

0

Il modo più semplice per convertire in modo sicuro in un valore 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'

0

Se la tua API accetta solo le stringhe "true" o "false", con tutto il resto che diventanull , allora prova:

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

Questo presuppone che $inputnon sia un oggetto. Null coalesce ( ??) è stato introdotto in PHP 7.0.

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.