Условия и сравнение: == vs ===
Условия - это то, что спасает твой код от жизни «на авось». И да, сегодня мы разберём легендарную битву: == против ===.
if / else
<?php
$age = 17;
if ($age >= 18) {
echo 'Проходи';
} else {
echo 'Приходи через год';
}
elseif (цепочка условий)
<?php
$score = 83;
if ($score >= 90) {
echo 'A';
} elseif ($score >= 75) {
echo 'B';
} elseif ($score >= 60) {
echo 'C';
} else {
echo 'F';
}
Сравнение: == vs ===
==сравнивает значения и может приводить типы (см. type juggling в уроке про переменные)===сравнивает и значение, и тип
Примеры, которые ломают судьбы новичков:
<?php
var_dump('0' == 0); // true - строка "0" приводится к числу
var_dump('0' === 0); // false - строка и число - разные типы
var_dump('' == false); // true - пустая строка «как будто false»
var_dump('' === false); // false - строка и bool - разные типы
var_dump(0 == null); // true - 0 «как будто null»
var_dump(0 === null); // false - число и null - разные типы
Тернарный оператор
Короткая запись if/else для присваивания:
<?php
$age = 20;
$status = ($age >= 18) ? 'взрослый' : 'ребёнок';
echo $status; // "взрослый"
// Удобно для вывода:
echo 'Роль: ' . ($isAdmin ? 'Администратор' : 'Пользователь');
Оператор ?? (null coalescing)
Возвращает первое «не null» значение:
<?php
$name = $_GET['name'] ?? 'Гость';
// Если $_GET['name'] не существует или null → 'Гость'
// Цепочка:
$config = $customConfig ?? $envConfig ?? $defaultConfig;
Оператор ??= (PHP 7.4+) - присвоить, если null:
<?php
$user['role'] ??= 'viewer'; // если role не задан → ставим 'viewer'
Логические операторы
<?php
$isLoggedIn = true;
$isAdmin = false;
// && (И) - оба должны быть true
if ($isLoggedIn && $isAdmin) {
echo 'Админ-панель';
}
// || (ИЛИ) - хотя бы одно true
if ($isLoggedIn || $isAdmin) {
echo 'Есть доступ';
}
// ! (НЕ) - инвертирует
if (!$isAdmin) {
echo 'Ты не админ';
}
Ленивое вычисление (short-circuit): если первая часть && - false, вторая не проверяется. Это полезно:
<?php
// Безопасно: если $user null, ->isActive() не вызовется
if ($user !== null && $user->isActive()) {
echo 'Активный пользователь';
}
switch
<?php
$role = 'editor';
switch ($role) {
case 'admin':
echo 'Полный доступ';
break;
case 'editor':
echo 'Можно редактировать';
break;
default:
echo 'Только читать';
}
match (PHP 8+)
Современная замена switch - без fall-through и со строгим сравнением:
<?php
$role = 'editor';
$access = match ($role) {
'admin' => 'Полный доступ',
'editor' => 'Можно редактировать',
default => 'Только читать',
};
echo $access;
Отличия от switch: match использует === (строгое сравнение), возвращает значение, не нужен break, и выбрасывает UnhandledMatchError, если ни один case не подошёл и нет default.
<?php
// Несколько значений в одном case:
$httpCode = 404;
$message = match ($httpCode) {
200, 201 => 'OK',
301, 302 => 'Redirect',
404 => 'Not Found',
500, 502 => 'Server Error',
default => 'Unknown',
};
Spaceship-оператор <=>
Возвращает -1, 0 или 1 - удобен для сортировки:
<?php
echo 1 <=> 2; // -1 (первый меньше)
echo 2 <=> 2; // 0 (равны)
echo 3 <=> 2; // 1 (первый больше)
// В usort:
$users = [['age' => 25], ['age' => 18], ['age' => 30]];
usort($users, fn($a, $b) => $a['age'] <=> $b['age']);
Приведение типов в условиях
PHP приводит значения к bool в условиях. Что считается false:
<?php
// Все эти значения - falsy (приводятся к false):
if (false) {} // false
if (0) {} // ноль
if (0.0) {} // ноль с плавающей точкой
if ('') {} // пустая строка
if ('0') {} // строка "0" - сюрприз!
if ([]) {} // пустой массив
if (null) {} // null
Типичные ошибки
- Ловушки
==с приведением типов."0abc" == 0→true(старая версия PHP до 8.0 кастит строку в число),"" == null→true,0 == "any string"в PHP 7 тожеtrue. Сравнивай через===и!==- это единственный способ не наступить на грабли. - Висящий fall-through в
switch. Забылbreak- выполнение «провалилось» в следующийcaseи сделало то, чего ты не ждал. Если fall-through нужен намеренно - оставь комментарий// fallthrough, чтобы ревьюер понял. - Отсутствие
defaultвswitch/match. Вswitchбезdefaultнеподходящий ввод тихо игнорируется и баг всплывёт через неделю. ВmatchбудетUnhandledMatchError- лучше явно бросить исключение, чем молча проглотить. - Путаница
switchvsmatch.switchиспользует==(нестрогое),match-===(строгое) и возвращает значение. Не путай:match (1) { "1" => ... }не сработает, аswitch (1) { case "1": ... }- сработает. Для новой логики бериmatch. - Неявная истинность строк.
if ("0")-false,if ("0.0")-true,if ("false")-true. Если проверяешь «строка не пуста», пиши$str !== '', а неif ($str).
Best practices
-
Используй
===и!==по умолчанию;==оставь только когда осознанно нужен juggling. -
Предпочитай
matchвместоswitchв новом коде - строгое сравнение, возврат значения, нет fall-through. -
Всегда добавляй
default(или явныйthrow new \UnexpectedValueException(...)) вswitch/match, чтобы неожиданный ввод не молчал. -
Для проверки «значение есть» пиши конкретно:
$x !== null,$str !== '',count($arr) > 0- а не полагайся на truthy-приведение. -
Не вкладывай тернарники и не комбинируй
??с?:без скобок - читаемость падает быстрее, чем кажется. -
Python - Условные конструкции: if, elif, walrus (:=) - те же паттерны в Python: тернарный, match-case (Python 3.10+)
Мини-задание
- Напиши проверку логина: если
$user !== null- «Привет», иначе - «Войди» - Проверь разницу
==и===на примерах:"10"и10,""и0,nullиfalse - Перепиши цепочку
if/elseifчерезmatch(PHP 8+) - Используй
??для безопасного чтения$_GET['page']с дефолтом - Напиши
usortс оператором<=>для сортировки массива пользователей по возрасту