Недавно мне понадобилась «свободная» функция логического преобразования для обработки строк, подобных тем, о которых вы спрашиваете (среди прочего). Я нашел несколько разных подходов и придумал большой набор тестовых данных для их обработки . Ничего не подходило под мои нужды, поэтому я написал свое:
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;
}
}
Обратите внимание, что для объектов, которые являются как счетными, так и строковыми, это предпочтет счетчику над строковым значением для определения истинности. То есть, если $object instanceof Countable
это вернется (boolean) count($object)
независимо от значения (string) $object
.
Вы можете увидеть поведение для тестовых данных , которые я использовал, а также результаты для ряда других функций здесь . Трудно просмотреть результаты этого маленького iframe, поэтому вместо этого вы можете просматривать вывод скрипта на полной странице (этот URL-адрес недокументирован, поэтому это может не работать вечно). На тот случай, если эти ссылки когда-нибудь умрут, я также помещаю код на pastebin .
Граница между тем, что «должно быть правдой» и что не должно, довольно условна; данные, которые я использовал, сгруппированы в зависимости от моих потребностей и эстетических предпочтений, ваши могут отличаться.
isBoolean("")
должно возвращаться false.