До основного вмісту

strict_types і строга типізація PHP у проді

PHP · 29.09.2026

Що насправді робить 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.

Зі 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 і розраховані на строгу типізацію за замовчуванням.

Типи властивостей, параметрів і повернення: приклади

КонструкціяПрикладЩо перевіряє 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 на проді.
  • Зміну впроваджено поступово, по одному модулю, із прогоном тестів після кожного файлу.
← Назад до бази знань Поставити питання підтримці