Parsowanie ciągu znaków do wartości logicznej w PHP

Dzisiaj grałem w PHP i odkryłem, że wartości łańcuchowe "true" I "false" nie są poprawnie parsowane do boolean w warunku, na przykład biorąc pod uwagę następującą funkcję:

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

Jeśli wykonam:

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

Wydaje się działać tylko z wartościami " 1 "i " 0":

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

Czy istnieje natywna funkcja w PHP do parsowania łańcuchów" true "I" false " na logiczne?

Author: Mark, 2011-01-23

7 answers

Istnieje natywna metoda PHP, która używa metody filter_var PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

Według instrukcji PHP :

Zwraca TRUE dla "1", "true", " on " i "yes". W przeciwnym razie zwraca FALSE.

Jeśli filter_null_on_failure jest ustawiony, FALSE jest zwracane tylko dla "0", "false", "off", " no "i"", a NULL jest zwracane dla wszystkich wartości nie-boolowskich.

 342
Author: Eric Caron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 10:56:59

Powodem jest to, że wszystkie łańcuchy wartościują true podczas konwersji na wartość logiczną, z wyjątkiem "0" i "" (pusty łańcuch).

Następująca funkcja zrobi dokładnie to, co chcesz: zachowuje się dokładnie tak jak PHP, ale będzie również oceniać łańcuch "false" jako false:

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

Dokumentacja wyjaśnia, że: http://php.net/manual/en/language.types.boolean.php :

Podczas konwersji na wartość logiczną następujące wartości są uważane za FALSE:

  • The boolean FALSE itself
  • liczba całkowita 0 (zero)
  • float 0.0 (zero)
  • pusty łańcuch i łańcuch " 0 "
  • tablica z zerowymi elementami
  • specjalny typ NULL (zawierający zmienne unset)
  • Obiekty SimpleXML utworzone z pustych tagów

Każda inna wartość jest uważana za prawdziwą(łącznie z dowolnym zasobem).

 13
Author: arnaud576875,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-23 18:13:27

Tylko w PHP {[2] } lub pusty łańcuch powoduje wymuszenie na false; każdy inny niepusty łańcuch powoduje wymuszenie na true. Z instrukcji :

Podczas konwersji na boolean, następujące wartości są brane pod uwagę FALSE:

  • pusty łańcuch i łańcuch " 0 "

Musisz napisać własną funkcję do obsługi łańcuchów "true" vs "false". Tutaj zakładam, że wszystko inne domyślnie ma wartość false:

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

Na marginesie, który łatwo może być skondensowane do

function isBoolean($value) {
   return $value === "true";
}
 4
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-23 17:40:46

Używam tego konstruktu do przekształcania łańcuchów w booleany, ponieważ chcesz true dla większości innych wartości:

$str = "true";
$bool = !in_array($str, array("false", "", "0", "no", "off"));
 3
Author: mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-23 17:50:18

Ostatnio potrzebowałem "luźnej" funkcji konwersji logicznej do obsługi łańcuchów takich jak te, o które pytasz (między innymi). znalazłem kilka różnych podejść i wymyśliłem duży zestaw danych testowych, aby je przejrzeć. Nic do końca nie pasuje do moich potrzeb więc napisałem swoje:

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

Zauważ, że dla obiektów, które są zarówno policzalne, jak i String-castable, będzie to faworyzować liczbę nad wartością string w celu określenia prawdziwości. Oznacza to, że jeśli $object instanceof Countable to zwróci (boolean) count($object) niezależnie od wartości (string) $object.

Możesz zobaczyć zachowanie danych testowych, których użyłem, a także wyniki kilku innych funkcji tutaj. Trochę trudno jest przejrzeć wyniki z tego małego iframe ' a, więc możesz zobaczyć wyjście skryptu na pełnej stronie, zamiast tego (Ten adres URL jest nieudokumentowany, więc może to nie działać wiecznie). W przypadku, gdy te linki kiedyś umrą, umieściłem kod na pastebin , jak również.

Granica między tym, co "powinno być prawdziwe" a co nie jest dość arbitralne; dane, których użyłem, są kategoryzowane w oparciu o moje potrzeby i preferencje estetyczne, Twoje mogą się różnić.

 2
Author: Matt Kantor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-16 01:28:52

Czy istnieje funkcja w PHP do parsowania łańcuchów" true "I" false " na logiczne?

Nie-oba są ciągami, a te oba (jak mówisz) oceniają na true. Tylko puste łańcuchy w PHP są oceniane do false.

Musisz to sprawdzić ręcznie. Jeśli w ogóle jest to możliwe, lepiej byłoby pracować z "prawdziwymi" wartościami logicznymi.
 1
Author: Pekka 웃,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-23 17:48:23

Najprostszy sposób na bezpieczną konwersję na wartość logiczną;

    $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
Author: Timothy Perez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 15:17:35