Как преобразовать строку в логическое значение (boolean) в PHP?
Проблема с приведением типов в PHP
Вы столкнулись с классической ловушкой PHP. Прямое приведение (bool) $string работает по правилам "истинности" строк: любая непустая и не равная "0" строка считается true. Поэтому (bool) "false" даёт true, ведь строка "false" не пустая.
Для решения задачи нужно явно интерпретировать содержимое строки. Есть несколько способов, от простого до более продвинутого.
Способ 1: Функция filter_var() (рекомендуемый)
В PHP есть встроенная функция filter_var() с фильтром FILTER_VALIDATE_BOOLEAN. Она обрабатывает строки "true", "false", "1", "0", "yes", "no", "on", "off" (регистронезависимо) и возвращает соответствующий булевый тип.
<?php
function toBool($string) {
return filter_var($string, FILTER_VALIDATE_BOOLEAN);
}
// Примеры:
var_dump(toBool("true")); // bool(true)
var_dump(toBool("false")); // bool(false)
var_dump(toBool("1")); // bool(true)
var_dump(toBool("0")); // bool(false)
var_dump(toBool("yes")); // bool(true)
var_dump(toBool("no")); // bool(false)
var_dump(toBool("on")); // bool(true)
var_dump(toBool("off")); // bool(false)
var_dump(toBool("TRUE")); // bool(true)
var_dump(toBool("FALSE")); // bool(false)
var_dump(toBool("любая другая строка")); // bool(false)
?>
Важно: filter_var() для нераспознанных строк возвращает false. Если вам нужно строго различать "неверный ввод" и "ложь", используйте третий параметр:
$result = filter_var($string, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
// Вернёт null для неподдерживаемых строк, true или false — для корректных.
Способ 2: Собственная функция с маппингом
Если вам нужен полный контроль над списком допустимых значений, напишите свою функцию:
<?php
function stringToBool($string) {
$trueValues = ['true', '1', 'yes', 'on', 'y', 't'];
$falseValues = ['false', '0', 'no', 'off', 'n', 'f', ''];
$lower = strtolower(trim($string));
if (in_array($lower, $trueValues, true)) {
return true;
}
if (in_array($lower, $falseValues, true)) {
return false;
}
// Если строка не распознана — можно вернуть null или выбросить исключение
throw new InvalidArgumentException("Невозможно преобразовать '$string' в boolean");
}
// Использование:
try {
$flag = stringToBool("yes"); // true
$flag2 = stringToBool("FALSE"); // false
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
?>
Способ 3: Для работы с JSON
Если строки приходят из JSON (например, из API), используйте json_decode():
$bool = json_decode('true'); // bool(true)
$bool = json_decode('false'); // bool(false)
// Внимание: json_decode('"true"') вернёт строку, а не boolean!
Итоговые рекомендации
- Для большинства случаев используйте
filter_var()— он покрывает 95% потребностей. - Если нужен строгий контроль (например, только "true"/"false") — напишите свою функцию.
- Не используйте
(bool)для строк, приходящих от пользователя, — это приведёт к ошибкам. - Всегда учитывайте, что
filter_var()считает нераспознанные строки какfalse. Если это критично, используйтеFILTER_NULL_ON_FAILURE.
Альтернативный подход: использование match-выражения (PHP 8.0+)
Если вы используете PHP 8.0 или новее, можно элегантно решить задачу с помощью match:
<?php
function toBool(string $value): bool {
return match (strtolower(trim($value))) {
'true', '1', 'yes', 'on', 'y', 't' => true,
'false', '0', 'no', 'off', 'n', 'f', '' => false,
default => throw new InvalidArgumentException("Unknown boolean string: $value")
};
}
// Пример:
echo toBool('Yes') ? 'Истина' : 'Ложь'; // Истина
echo toBool('0') ? 'Истина' : 'Ложь'; // Ложь
?>
Плюсы: код читаемый, легко расширять список значений, строгая типизация.
Минусы: требует PHP 8.0+, нужно обрабатывать исключение для неизвестных значений.
Если данные приходят из HTML-форм
Учтите, что из формы с checkbox приходит либо строка "on" (если отмечен), либо вообще ничего. Для этого случая:
$isChecked = isset($_POST['agree']) && $_POST['agree'] === 'on';
Или используйте filter_input():
$isChecked = filter_input(INPUT_POST, 'agree', FILTER_VALIDATE_BOOLEAN);
Этот способ безопаснее и сразу возвращает правильный boolean.
Ответов пока нет.
Войдите чтобы оставить ответ