# 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/uk/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/uk/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/uk/kb/php-strict-types-tipizaciya/
