Что такое директива declare(strict_types=1) в PHP?

Ответ

Директива declare(strict_types=1); включает режим строгой типизации (strict types) для скалярных типов в конкретном PHP-файле. Она должна быть объявлена самой первой строкой в файле, до любого другого кода (кроме <?php).

Что меняется при включении strict_types=1: PHP перестаёт выполнять неявные, потенциально опасные преобразования типов для аргументов функций и возвращаемых значений, которые используют скалярные type hints (int, float, string, bool). Вместо этого происходит строгая проверка на точное соответствие.

Сравнительный пример:

// ФАЙЛ БЕЗ strict_types (поведение по умолчанию)
function add(int $a, int $b): int {
    return $a + $b;
}

echo add("10", 5.5); // Выведет 15
// PHP неявно приводит "10" к 10, а 5.5 к 5.
// ФАЙЛ СО strict_types=1
<?php
declare(strict_types=1); // Критически важная строка

function add(int $a, int $b): int {
    return $a + $b;
}

echo add("10", 5.5); // TypeError! Аргумент 1 должен быть типа int, string передано.

Ключевые особенности:

  • Файловая область видимости: Директива действует только на файл, в котором она объявлена. Если файл A с strict_types=1 вызывает функцию из файла B без этой директивы, для вызова из A будут применяться строгие правила, но внутри B — нет.
  • Только для пользовательских функций: Не влияет на встроенные функции PHP (например, strlen() или array_merge).
  • Выбрасывает TypeError: При несоответствии типа выбрасывается исключение TypeError, которое можно отловить.

Практическая польза:

  1. Предотвращение скрытых багов: Исключает неочевидные преобразования, которые могут исказить логику (например, строка "123abc" станет числом 123).
  2. Повышение читаемости: Код становится более предсказуемым — типы в сигнатуре функции точно описывают, что она принимает и возвращает.
  3. Подготовка к современному PHP: Строгая типизация — стандарт в современной разработке на PHP, особенно в сочетании с инструментами статического анализа (Psalm, PHPStan).

Рекомендация: Всегда использовать declare(strict_types=1); в новых проектах и при рефакторинге legacy-кода для повышения его надёжности.

Ответ 18+ 🔞

Э, слушай, вот тебе насущный вопрос, как в жизни. Представь, ты пишешь код, а PHP, как тот хитрожопый сосед, начинает сам всё переделывать. Передал строку в функцию, где нужен int? Да похуй, он её сам в число превратит, лишь бы не ругаться. Это ж пиздец какой-то, доверия ебать ноль к такой логике.

Так вот, чтобы этот цирк прекратить, есть волшебная строчка: declare(strict_types=1);. Это как взять и впендюрить PHP по башке, чтобы он перестал выёбываться и начал делать то, что ему говорят.

Что это, ёпта, такое? Это директива, которая включает режим строгой типизации для скалярных типов (int, float, string, bool). Но работает она только в том файле, где её написал, и должна стоять самой первой хуйнёй после <?php, иначе будет тебе хиросима в виде ошибки.

Ну и что она делает-то, ядрёна вошь? А делает она простую вещь: выключает эти ебушки-воробушки с неявным преобразованием типов в аргументах функций и возвращаемых значениях. Теперь PHP будет орать TypeError, если ты передашь не то, что указал.

Смотри, как было и как стало:

// ФАЙЛ БЕЗ strict_types (обычный бардак)
function add(int $a, int $b): int {
    return $a + $b;
}

echo add("10", 5.5); // Выведет 15
// PHP сам додумал: "10" -> 10, 5.5 -> 5. Итог: 15. А ты сиди и гадай, откуда пятёрка взялась.
// ФАЙЛ СО strict_types=1 (порядок и ясность)
<?php
declare(strict_types=1); // Вот она, палочка-выручалочка!

function add(int $a, int $b): int {
    return $a + $b;
}

echo add("10", 5.5); // БАБАХ! TypeError! Аргумент 1 должен быть int, а ты сука строку суёшь.

Важные нюансы, чтобы не облажаться:

  • Действует только на свой файл: Это не глобальная настройка. Если твой файл с strict_types=1 вызывает функцию из другого файла без неё, то для этого вызова правила строгие, а внутри той функции — как обычно. Голова кругом, но так уж оно устроено.
  • Только для твоих функций: На встроенные функции PHP вроде strlen() или array_merge эта директива не действует. Они как жили по своим диким законам, так и живут.
  • Кидает TypeError: При несоответствии не будет молчаливого костыля — будет брошено исключение TypeError, которое можно и нужно ловить.

Зачем это всё, чувак?

  1. Баги нахуй: Больше никаких скрытых преобразований, когда строка "123abc" волшебным образом становится числом 123. Ты сразу видишь, где косяк.
  2. Код как книга: Сигнатура функции теперь — это закон. Что написано, то и должно быть. Никаких сюрпризов.
  3. Привет, современный мир: Все нормальные инструменты вроде PHPStan или Psalm обожают строгую типизацию. Это стандарт для любого адекватного проекта.

Итог: Если не хочешь, чтобы твой код был пиздопроебибной лотереей, вставляй declare(strict_types=1); в каждый новый файл. Для старого легаси-кода — тоже постепенно внедряй, когда рефакторишь. Сначала, конечно, охуеешь от количества ошибок, но потом спасибо себе скажешь.