Niedawno potrzebowałem „luźnej” funkcji konwersji wartości boolowskiej 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 nie pasowało do moich potrzeb, więc napisałem własne:
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 w przypadku obiektów, które są zarówno policzalne, jak i rzucane na łańcuchy, będzie to faworyzować liczenie względem wartości ciągu w celu określenia prawdziwości. Oznacza to, że jeśli $object instanceof Countable
zwróci to (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 dla kilku innych funkcji tutaj . Trudno jest przejrzeć wyniki z tego małego elementu iframe, więc zamiast tego można wyświetlić wynik skryptu na pełnej stronie (ten adres URL jest nieudokumentowany, więc może to nie działać wiecznie). Na wypadek, gdyby te linki pewnego dnia umarły, umieściłem kod również na pastebinie .
Granica między tym, co „powinno być prawdą”, a tym, co nie powinno, jest dość arbitralna; dane, których użyłem, są kategoryzowane w oparciu o moje potrzeby i preferencje estetyczne, Twoje mogą się różnić.
isBoolean("")
powinno zwrócić false.