Булев или булевый (логический, бинарный) это простейший тип данных. Его значение выражается истинностью или ложью - либо TRUE, либо FALSE, был введен начиная с PHP4. При определении булева типа используется ключевое слово TRUE или FALSE, оба регистро-независимы.
В примерах ниже мы будем использовать заранее заготовленные функции:
<?php function EmptyReturn(){} function SimpleReturn(){ return; } function ReturnNull(){ return null; } function ReturnFalse(){ return false; } function ReturnTrue(){ return true; } function ReturnZero(){ return 0; } function ReturnZeroString(){ return '0'; } function ReturnOneString(){ return '1'; }
Отображение булева типа с помощью функции var_dump();
- Код:
var_dump(EmptyReturn());
- вернёт: null - Код:
var_dump(SimpleReturn());
- вернёт: null - Код:
var_dump(ReturnNull());
- вернёт: null - Код:
var_dump(ReturnFalse());
- вернёт: boolean false - Код:
var_dump(ReturnTrue());
- вернёт: boolean true - Код:
var_dump(ReturnZero());
- вернёт: int 0 - Код:
var_dump(ReturnZeroString());
- вернёт: string '0' (length=1) - Код:
var_dump(ReturnOneString());
- вернёт: string '1' (length=1)
Отображение булева типа с помощью функции echo ...;
- Код:
echo EmptyReturn();
- выведет: "" - Код:
echo SimpleReturn();
- выведет: "" - Код:
echo ReturnNull();
- выведет: "" - Код:
echo ReturnFalse();
- выведет: "" - Код:
echo ReturnTrue();
- выведет: "1" - Код:
echo ReturnZero();
- выведет: "0" - Код:
echo ReturnZeroString();
- выведет: "0" - Код:
echo ReturnOneString();
- выведет: "1" - Код:
echo true;
- выведет: "1"
Вопрос: Почему "echo ReturnTrue();
" выводит "1"? Ответ: Потому, что в любых выражениях, в которых должна быть строка, происходит автоматическое преобразование в требуемый тип. Например когда мы сравниваем строку со значением переменной либо используем print()
или echo()
.
- Булево (boolean) значение
FALSE
всегда представляется как пустая строка (""), а значениеTRUE
всегда преобразуется в строку "1". - Число с плавающей точкой (float) или целое число (integer) преобразуется в строку, представленную числом, которое состоит из цифр (для чисел с плавающей точкой включая показатель степени).
- Массивы (array) всегда преобразуются в строку "Array", потому мы не сможем узнать содержимое массива при помощи
print()
илиecho()
. - Объекты преобразуются в строку "Object".
- Ресурсы (resource) в строки со структурой "Resource id #1", где 1 - является уникальным номером ресурса, который PHP присвоил ему во время выполнения скрипта. Для получения типа ресурса нужно использовать
get_resource_type()
. - NULL всегда преобразуется в "" (пустую строку).
Для вывода содержимого массивов, объектов или ресурсов можно использовать функции var_dump()
и print_r()
.
Операторы сравнения булева типа
В официальной документации PHP: Операторы сравнения - Manual сказано, что "Преобразование типов не происходит при использовании === или !== так как в этом случае кроме самих значений сравниваются еще и типы."
Код с оператором сравнения:if(ReturnTrue() !== true){echo 'FALSE'}else{echo 'TRUE'}
выдаст:TRUE
Код с оператором сравнения:if(ReturnOneString() !== true){echo 'FALSE'}else{echo 'TRUE'}
выдаст:FALSE
Иными словами, если мы используем оепратор сравнения !==
при сравнении булевого значения "1" в виде строки с булевым "TRUE
", то мы всегда будем получать "FALSE
". Для успешного сравнения как булевого типа так и его строкового значения, например "TRUE
" и "1", мы должны использовать операторы сравнени при которых происходит автоматическое преобразование типов "if("1" != true)
" или "if(!$a)
", либо явно выполнять преобразование типа "if((bool)"1" !== true)
".
Также следует иметь ввиду, что преобразование в булев тип любой строки (кроме (bool)"" и (bool)"0") будет равно = TRUE
!
Когда может потребоваться преобразование в булев тип
В некоторых ситуациях, некоторые функции по каким-то причинам могут возвращать булев тип TRUE
в виде строкового значения "1" в результате чего может быть получен заведомо ложный и непредсказуемый результат.
С одним из таких примеров пришлось познакомиться в движке PrestaShop, когда выполнялось обновление адреса доставки в "личном кабинете". При этом в некоторых случаях обновление адреса выполнялось без ошибок, а в некоторых завершалось ошибкой сервера (код 500 Internal Server Error), которая на удивление генерировалась самим движком с помощью header('HTTP/1.1 500 Internal Server Error');
, а не сервером. Исследование проблемы, после включения в движке режима разработчика и отображения всех ошибок PHP, вывело на кусок кода где выполнялось сравнение логического типа возвращаемых данных (или ака булев тип) в функции validateFields()
из файла /classes/ObjectModel.php:
function validateFields() { $message = $this->validateField($field, $this->$field); if ($message !== true) { ... throw new PrestaShopException($message); } }
echo gettype($message); exit;
в результате выдало "string", а echo $message;
показало "1", что в итоге использования оператора "!==
" закономерно привело к FALSE
результату.
Однако, мы видим, что переменная $message, в результате работы функции validateField()
кроме булева типа TRUE/FALSE может ещё содержать строку с сообщением об ошибках кидаемое в PrestaShopException($message)
класс /classes/exception/PrestaShopException.php, - а значит, конкретно в данном случае, преобразование строкового значения "1" в булев тип TRUE
может быть лишь временным решением проблемы и в идеале стоило бы отловить тот кусок кода, который возвращает логический тип TRUE
(ещё ака двоичные данные) в виде строкового значения "1".
Чтобы преобразование строки в булев тип было более безопасным, ведь мы знаем, что любая строка (только если это не "" или "0") после преобразования будет = TRUE
, что может создавать определённый риск для безопасности, можно поступить следующим, более безопасным, способом преобразования:
function validateFields() { $message = $this->validateField($field, $this->$field); if (gettype($message) == "string" || gettype($message) == "integer" && $message == "1") { $message = (bool)$message; } if ($message !== true) { ... throw new PrestaShopException($message); } }