/
Программирование
/
Курс PHP
/

Результат логических выражений

PHP: Результат логических выражений

В логических выражениях можно использовать не только значения типа bool. Числа и строки тоже могут быть операндами логических операций. В этом уроке разберем, как PHP обращается с ними и каким будет результат таких выражений.

Falsy и truthy значения

Когда значение попадает в логический контекст, PHP приводит его к true или false. В PHP есть фиксированный набор значений, которые считаются ложными (falsy). К ним относятся false, число 00.0), пустая строка '', строка '0', а также специальное значение null — «отсутствие значения».

Все остальные значения считаются истинными (truthy). Это, например, любое ненулевое число (1, -3.5) и непустая строка ('hi', 'hello').

Убедиться в этом можно с помощью двойного отрицания !!, которое приводит любое значение к типу bool: первое отрицание превращает значение в логическое (и инвертирует его), а второе возвращает обратно:

<?php

var_dump(!!'hello'); // => bool(true)  — непустая строка — truthy
var_dump(!!'');      // => bool(false) — пустая строка — falsy
var_dump(!!0);       // => bool(false) — ноль — falsy
var_dump(!!-3.5);    // => bool(true)  — ненулевое число — truthy
var_dump(!!'0');     // => bool(false) — строка '0' — falsy, особенность PHP

Этим приемом пользуются, чтобы явно поменять тип данных: результатом двойного отрицания всегда будет значение типа bool.

Как работают логические выражения

В некоторых языках операторы «И» и «ИЛИ» возвращают один из своих операндов, поэтому результатом может быть строка или число. PHP устроен иначе: логические операторы && и || всегда возвращают значение типа booltrue или false:

<?php

var_dump('hello' && 'world'); // => bool(true)  — оба операнда truthy
var_dump('' && 'world');      // => bool(false) — первый операнд falsy
var_dump(0 || 1);             // => bool(true)  — второй операнд truthy
var_dump('' || 0);            // => bool(false) — оба операнда falsy

Порядок вычисления зависит от приоритета операторов:

Приоритет (от высокого к низкому):

  ()          скобки
   ↓
  !           отрицание
   ↓
  &&          логическое И
   ↓
  ||          логическое ИЛИ

Нестрогое сравнение

Преобразование типов происходит и при нестрогом сравнении. Вспомните операторы == и != из урока про логический тип: они сравнивают значения, предварительно преобразовав типы. Поэтому, с точки зрения ==, пустая строка и false равны:

<?php

var_dump('' === false); // => bool(false)
var_dump('' == false);  // => bool(true)

Пустая строка и false — это разные значения, поэтому строгий оператор === говорит «Ложь! Они не равны!». Но оператор == преобразует операнды и считает их равными. Это преобразование неявное, поэтому по возможности избегайте операторов == и !=.

Ошибка выбора

Представим задачу, в которой нужно проверить, что значение равно либо одному, либо другому. Например, переменная $value должна содержать одно из двух значений: 'first' или 'second'. Начинающие разработчики иногда записывают это выражение так:

<?php

$value === ('first' || 'second');

В голове мы это себе примерно так и представляем, но языки работают по-другому, поэтому такой код приведет к неверному результату. Как его правильно прочитать? Первым делом вычисляется все, что указано в скобках, то есть 'first' || 'second'. Обе строки непустые, то есть truthy, поэтому результатом будет true. Теперь можно заменить исходное выражение на частично вычисленное:

<?php

$value === true;

Совсем не то, что мы ожидали: строка 'first' не равна true при строгом сравнении, поэтому выражение всегда ложно. А теперь вернемся к началу и напишем проверку правильно:

<?php

// Скобки ставить не обязательно,
// потому что приоритет === выше, чем приоритет ||
$value === 'first' || $value === 'second';

Задание

Напишите функцию isFalsy(), которая проверяет, трактуется ли переданное значение как ложное (falsy) с точки зрения PHP. Для выполнения этой проверки сравните переданное значение с false, используя нестрогое сравнение ==.

<?php

isFalsy(false);  // true
isFalsy(0);      // true
isFalsy('help'); // false
isFalsy(10);     // false

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются