Розбиття рядка на булеве значення в 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.