# strict_types и строгая типизация PHP на проде

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

## Что делает declare(strict\_types=1) на самом деле

Директива declare(strict\_types=1) должна стоять первой исполняемой строкой файла, сразу после открывающего тега \<?php. Она не включает типизацию как таковую — типы параметров и возврата можно указывать и без неё. Она меняет только одно: как PHP ведёт себя, когда переданное значение не совпадает по типу с объявленным.

Без strict\_types PHP пытается привести значение автоматически: строку "42" превратит в int 42, число 1 — в bool true. Со strict\_types=1 любое несовпадение типа, кроме безопасного расширения int в float, завершается исключением TypeError сразу в момент вызова функции, а не где-то внутри неё после нескольких строк логики.

## Слабая типизация: пример неявного приведения

Функция ниже объявляет параметр int, но без strict\_types PHP примет и строку, и число с плавающей точкой, молча обрезав дробную часть.

```
function applyDiscount(int $percent): float {
    return 100 - $percent;
}

echo applyDiscount("15abc"); // сработает как applyDiscount(15), без ошибки
```

Строка "15abc" не число, но PHP в нестрогом режиме отрежет часть, которая похожа на число, и выполнит функцию. Ошибка проявится не здесь, а там, где результат окажется неожиданно неверным — искать её придётся уже по логам, как описано в статье [о разборе логов PHP](https://www.zevshost.net/ru/kb/php-logi-oshibok-razbor/).

## Со strict\_types=1: та же ошибка ловится сразу

Тот же код с добавленной директивой в начале файла ведёт себя иначе — вместо тихого приведения происходит явный отказ.

```
declare(strict_types=1);

function applyDiscount(int $percent): float {
    return 100 - $percent;
}

echo applyDiscount("15abc");
// TypeError: applyDiscount(): Argument #1 ($percent) must be of type int, string given
```

Ошибка возникает на месте вызова, с точным номером строки, а не после нескольких шагов бизнес-логики. Это особенно важно для кода, написанного под PHP 8.3 и 8.4 — новые возможности этих версий разобраны в статье [о PHP 8.3 и 8.4](https://www.zevshost.net/ru/kb/php-84-novye-vozmozhnosti/) и рассчитаны на строгую типизацию по умолчанию.

## Типы свойств, параметров и возврата: примеры

| Конструкция | Пример | Что проверяет strict\_types |
| --- | --- | --- |
| Тип параметра | function f(int $x) | тип аргумента при вызове |
| Тип возврата | function f(): string | тип значения после return |
| Тип свойства класса | private float $price | тип при присваивании полю |
| Nullable-тип | function f(?int $x) | допускает int или null, не строку |

Nullable-типы и union-типы вида int\|string работают со strict\_types так же строго: любое значение, не входящее в объявленный список, вызывает TypeError.

## Где строгая типизация ломает существующий код

- Данные из $\_GET и $\_POST всегда приходят строками — их нужно явно приводить через (int) перед передачей в типизированную функцию.
- Значения из PDO по умолчанию тоже строки, даже для числовых колонок — без явного приведения strict\_types выбросит TypeError.
- Старые библиотеки без объявленных типов параметров продолжают работать как раньше, strict\_types их не затрагивает.
- JSON после json\_decode отдаёт числа как int или float в зависимости от содержимого — проверяйте тип перед передачей дальше.
- Тесты, написанные с расчётом на автоматическое приведение типов, начинают падать и требуют явных приведений в моках.

## Итог: чек-лист внедрения strict\_types

- declare(strict\_types=1) стоит первой строкой после \<?php в каждом файле проекта.
- Все входящие данные из $\_GET, $\_POST и PDO приводятся к нужному типу явно, а не полагаются на автоприведение.
- Параметры и возвращаемые значения публичных методов имеют объявленные типы, включая nullable и union.
- Новый TypeError отслеживается через error\_log, а не через display\_errors на проде.
- Изменение внедрено постепенно, по одному модулю, с прогоном тестов после каждого файла.

---

Источник: https://www.zevshost.net/ru/kb/php-strict-types-tipizaciya/
