Розбиття рядка на булеве значення в PHP


126

Сьогодні я грав з PHP, і я виявив, що значення рядків "true" і "false" неправильно розбираються на булеві умови, наприклад, враховуючи наступну функцію:

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

Якщо я виконую:

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

Здається, це працює лише зі значеннями "1" та "0":

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

Чи є нативна функція в PHP для аналізу "істинних" та "помилкових" рядків на булеві?


У вашому коді isBoolean("")повинно бути повернено помилкове.
BoltClock

Вам слід подумати про зміну прийнятої відповіді на відповідь Еріка Карона. Він показує вам нативну функцію, яка виконує те, що ви просите.
Командир коду

1
PHP не замислюється над тим, що говорить рядок, "false" - це лише п'ять символів, які нічого не означають. Вони є чимось , тому булеве значення оцінюється trueнавіть для людського читача, але здається, що це інтуїтивно зрозуміло FALSE.
zeel

Відповіді:


413

Для цього існує нативний метод PHP, який використовує метод filter_var PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

Відповідно до посібника PHP :

Повертає TRUE для "1", "true", "on" і "yes". Повертає FALSE в іншому випадку.

Якщо встановлено FILTER_NULL_ON_FAILURE, FALSE повертається лише для "0", "false", "off", "no" та "", а NULL повертається для всіх не boolean значень.


Це мала бути прийнятою відповіддю. Вбудовані функції PHP краще, ніж будувати власну. Не потрібно винаходити колесо! Шкода, що було занадто пізно: P
casraf

1
чи це також мале значення для порівняння?
Mobiletainment

3
@Mobiletainment, так - він обробляє будь-який корпус, який ви можете уявити собі за $ value (false, FALSE, FalSe тощо)
Ерік Карон

На моєму кінці згорнутий зразок. Для порівняння використовується == замість ===. Видаляю попередній коментар, щоб не бентежити людей.
andig

6
Відповідь застала мене осторонь, тому що ви повинні додати прапор FILTER_NULL_ON_FAILUREдо filter_var()функції, а НЕ замінити його FILTER_VALIDATE_BOOLEANтаким, як я думав. Це призведе до наступного коду, який зробив для мене трюк:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54

14

Причина полягає в тому, що всі рядки оцінюють trueпри перетворенні їх на булеві, крім "0"і"" (порожній рядок).

Наступна функція виконає саме те, що ви хочете: вона поводиться точно як PHP, але також оцінить рядок "false"як false:

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

Документація пояснює, що: http://php.net/manual/en/language.types.boolean.php :

При переході в булеві значення наступні значення вважаються ЛІЖНІМ:

  • булева ЛАШКА сама
  • ціле число 0 (нуль)
  • поплавок 0,0 (нуль)
  • порожній рядок і рядок "0"
  • масив з нульовими елементами
  • спеціальний тип NULL (включаючи невстановлені змінні)
  • Об'єкти SimpleXML, створені з порожніх тегів

Кожне інше значення вважається ПРАВИЛЬНИМ (включаючи будь-який ресурс).


2
+1 Приємно. (Чи міг би встромити стрітоловер там, але це про це.)
Джон Паркер

Я думаю, що middaparka означав порівняння strtolower ($ value) з "false". Передача буквального "хибного" в strtolower - це трохи .... дафт? :)
Пол Діксон

@Paul Dixon Yup, саме про це я мав на увазі. :-)
Джон Паркер

2
@Marco - якщо ($ value && strtolower ($ value)! == "faux") {якщо ви працюєте французькою мовою; if ($ value && strtolower ($ value)! == "falsch") {німецькою мовою; якщо ($ value && strtolower ($ value)! == "onwaar") {голландською мовою ... ви можете зрозуміти, чому для PHP це не вбудовано як стандарт
Марк Бейкер

1
"всі непусті рядки оцінюються як істинні при перетворенні їх на булеві, за винятком" 0 "."
BoltClock

5

Тільки в PHP "0"або порожній рядок примушує до false; кожен інший не порожній рядок примушує до істини. З посібника :

При перетворенні на булеві, враховуються такі значення FALSE:

  • порожній рядок і рядок "0"

Ви повинні написати свою власну функцію для обробки рядків "true"проти "false". Тут я припускаю, що все інше за замовчуванням має значення false:

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

Сторона записки, до якої легко можна було б стиснутись

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

4

Нещодавно мені потрібна була "вільна" булева функція перетворення для обробки рядків, таких як ті, про які ви запитуєте (серед іншого). Я знайшов кілька різних підходів і придумав великий набір тестових даних для пробігу через них . Нічого не відповідає моїм потребам, тому я написав своє:

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.

Тут ви можете побачити поведінку тестових даних, які я використав, а також результати для кількох інших функцій тут . Результати з цього маленького рамки кадрів важко схилити, тож ви можете замість цього переглядати вихід сценарію на повній сторінці (ця URL-адреса недокументована, тому це може не працювати назавжди). Якщо ці посилання в один прекрасний день помирають, я кладу код на пастбін .

Межа між тим, що "повинно бути правдою" і тим, що не повинно, є досить довільним; дані, які я використовував, класифікуються на основі моїх потреб та естетичних уподобань, ваші можуть відрізнятися.


Ця функція працює бездоганно, дякую! Але зараз ваші посилання 404.
servermanfail

3

Я використовую цю конструкцію для перетворення рядків у булеві, оскільки ви хочете trueдля більшості інших значень:

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

1

Чи є в PHP функція аналізувати рядки "true" та "false" на булеві?

Ні - обидва - це рядки, і ті, що обидва (як ви кажете) оцінюєте true. falseУ PHP оцінюються лише порожні рядки .

Вам потрібно буде перевірити це вручну. Якщо це взагалі можливо, краще було б працювати з "справжніми" булевими значеннями.


1
Не всі рядки оцінюються trueв PHP.
coreyward

1
Не виправляв, просто уточнював. Скажіть, що "обидва - це рядки [і оцінювати до true]", може створити на новачка неправильне враження, особливо це стосується іншої мови з більш суворими правилами введення тексту, де рядок є рядком, а вміст не має значення при перетворенні на булевий (наприклад Рубін).
coreyward

1
"Лише порожні рядки в PHP оцінюються як хибні." А як же не порожня рядок "0"? Це також не оцінює false?
Сепстер

0

Найпростіший спосіб безпечного перетворення на булевий;

    $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

Якщо ваш API приймає лише рядки "true" або "false", а все інше станеnull , спробуйте:

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

Це передбачає, що $inputце не об’єкт. Null coalesce ( ??) був введений в PHP 7.0.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.