Урок 05

Условия: if, else, switch

Что такое условия

Условие — конструкция, которая выполняет код только при определённом состоянии.

Пример из жизни:

ЕСЛИ на улице дождь → взять зонт
ИНАЧЕ → не брать

if

Простейшая форма:

if ($age >= 18) {
    echo 'Доступ разрешён';
}

Синтаксис:

if (условие) {
    // код
}

Условие — любое выражение, приводимое к bool.

if / else

if ($age >= 18) {
    echo 'Взрослый';
} else {
    echo 'Ребёнок';
}

if / elseif / else

if ($score >= 90) {
    echo 'Отлично';
} elseif ($score >= 75) {
    echo 'Хорошо';
} elseif ($score >= 60) {
    echo 'Удовлетворительно';
} else {
    echo 'Неудовлетворительно';
}

Порядок важен — проверки идут сверху вниз, первое совпадение останавливает цепочку.

elseif и else if — одно и то же, стилистически чаще elseif.

Вложенные условия

if ($user !== null) {
    if ($user->isActive) {
        if ($user->hasSubscription) {
            echo 'Доступ к премиуму';
        }
    }
}

Плохо — вложенность тяжело читать.

Лучше — early return:

function canAccessPremium(?User $user): bool
{
    if ($user === null) return false;
    if (!$user->isActive) return false;
    if (!$user->hasSubscription) return false;

    return true;
}

Правило: старайся уменьшить вложенность через «ранние выходы».

Альтернативный синтаксис

Для шаблонов:

<?php if ($user): ?>
    <h1>Привет, <?= $user->name ?></h1>
<?php else: ?>
    <h1>Гость</h1>
<?php endif; ?>

Работает также для foreach, while, for:

<?php foreach ($items as $item): ?>
    <li><?= $item ?></li>
<?php endforeach; ?>

Используется в шаблонах (Blade в Laravel — свой синтаксис, но идея та же).

switch

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

switch ($status) {
    case 'active':
        echo 'Активен';
        break;
    case 'pending':
        echo 'Ожидает';
        break;
    case 'blocked':
        echo 'Заблокирован';
        break;
    default:
        echo 'Неизвестный статус';
}

Особенности:

  • break — обязателен, иначе «провалится» в следующий case.
  • default — сработает, если ни один case не совпал.
  • Сравнение через ==, не === — опасно.

Fall-through

Если пропустить break:

switch ($day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        echo 'Рабочий день';
        break;
    case 6:
    case 7:
        echo 'Выходной';
        break;
}

Полезно, когда несколько значений обрабатываются одинаково.

Случайно пропущенный break — классический баг.

switch vs if

switch:

  • Одно значение — много вариантов.
  • Чище, чем длинная цепочка if/elseif.

if:

  • Сложные условия ($a > 5 && $b < 10).
  • Разные проверки.

Правило: если проверяется одна переменная на равенство — switch.

match (PHP 8+)

Современная замена switch:

$message = match ($status) {
    'active' => 'Активен',
    'pending' => 'Ожидает',
    'blocked' => 'Заблокирован',
    default => 'Неизвестный статус',
};

Отличия от switch:

  • Возвращает значение.
  • Строгое сравнение (===).
  • Не требует break.
  • Все случаи должны быть покрыты, иначе UnhandledMatchError.

Несколько значений:

$type = match ($code) {
    200, 201, 204 => 'Успех',
    400, 422 => 'Ошибка клиента',
    500, 502 => 'Ошибка сервера',
    default => 'Другое',
};

С условиями:

$grade = match (true) {
    $score >= 90 => 'Отлично',
    $score >= 75 => 'Хорошо',
    $score >= 60 => 'Удовлетворительно',
    default => 'Неудовлетворительно',
};

match (true) — паттерн для замены if/elseif.

Оператор ?:

Тернарник:

$status = $age >= 18 ? 'взрослый' : 'ребёнок';

Читается плохо, если вложенный:

// Плохо
$msg = $a ? $b : ($c ? $d : $e);

// Лучше — match или if

Truthy и falsy

Falsy-значения:

false
0
0.0
''
'0'
[]
null

Всё остальное — truthy.

Практика:

if ($items) {          // пустой массив — false
    echo count($items);
}

if ($name) {           // пустая строка — false
    echo "Привет, $name";
}

⚠️ '0' — falsy! Классическая ловушка:

$input = '0';
if ($input) {
    echo 'Значение есть';   // не сработает!
}

if ($input !== '') {        // правильно
    echo 'Значение есть';
}

Вложенные проверки без вложенности

Раньше:

if ($user) {
    if ($user->isActive) {
        if ($user->email) {
            sendEmail($user);
        }
    }
}

Сейчас:

if (!$user) return;
if (!$user->isActive) return;
if (!$user->email) return;

sendEmail($user);

Guard clauses — паттерн «ранних выходов».

Примеры

Проверка доступа

function canEditPost(User $user, Post $post): bool
{
    if ($user->isAdmin) {
        return true;
    }

    return $post->authorId === $user->id;
}

Категория товара

$category = match (true) {
    $price < 1000 => 'Дешёвый',
    $price < 10000 => 'Средний',
    $price < 100000 => 'Дорогой',
    default => 'Премиум',
};

Роутинг

switch ($path) {
    case '/':
        require 'pages/home.php';
        break;
    case '/about':
        require 'pages/about.php';
        break;
    case '/contact':
        require 'pages/contact.php';
        break;
    default:
        http_response_code(404);
        require 'pages/404.php';
}

Практика

<?php

declare(strict_types=1);

$age = 25;
$hasLicense = true;
$isDrunk = false;

$canDrive = match (true) {
    $age < 18 => 'Слишком молод',
    !$hasLicense => 'Нет прав',
    $isDrunk => 'Нельзя за руль',
    default => 'Можно ехать',
};

echo $canDrive;

Итог

  • if — базовое условие.
  • elseif/else — продолжение.
  • switch — много вариантов одной переменной, break обязателен.
  • match (PHP 8+) — современная замена, возвращает значение, строгое сравнение.
  • ?: — короткий тернарник.
  • Falsy: false, 0, '', '0', [], null.
  • Guard clauses — уменьшай вложенность.

Дальше — циклы: for, while, foreach.