• Час читання ~1 хв
  • 24.05.2023

Вступ

Якщо ви розробник PHP, ви, напевно, бачили твердження declare(strict_types=1) на початку деяких файлів PHP.

Перший раз, коли я побачив цю заяву, я поняття не мав, що вона робить. Я припустив, що це якийсь коментар або, можливо, якийсь старий синтаксис PHP, який був до мого часу, але я помилявся (дуже помилявся!).

У цій статті Quickfire ми розглянемо, що declare(strict_types=1) таке і як це може допомогти вам підвищити безпеку типу вашого PHP-коду.

Що такеdeclare(strict_types=1)?

declare(strict_types=1) is a statement that enforces strict typing in PHP applications.

Коли ви використовуєте цю інструкцію, PHP виконає сувору перевірку параметрів функцій і типів повернення. Це означає, що якщо функція очікує певного типу параметра або значення, що повертається, PHP видасть помилку, якщо використовується неправильний тип.

Давайте візьмемо простий приклад, який не використовує declare(strict_types=1):

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

Тепер скажімо, ми викликали цю функцію з параметрами рядка:

echo add('1', '2');
 
// Output:
// 3

PHP will happily convert the string parameters to integers and return the result 3.

У деяких випадках вас може цілком влаштовувати така поведінка. Але це може мати деякі непередбачені наслідки, яких ви не очікували, і які можуть спричинити помилки у вашій програмі.

Однак давайте уявимо, що ми хотіли використовувати declare(strict_types=1) в цьому прикладі. Ми могли б зробити це, додавши наступну інструкцію у верхній частині файлу:

declare(strict_types=1);
 
function add(int $a, int $b): int
{
    return $a + $b;
}

Тепер, якщо ми викличемо функцію з параметрами рядка, PHP видасть помилку:

echo add('1', '2');
 
// Output:
// Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type int, string given
As we can see here, PHP has thrown an error because the add function expected integers to be passed, but received strings instead.

Аналогічно, PHP також викине add помилки, якщо ввімкнено сувору перевірку типу, і ми спробуємо повернути неправильний тип даних із методу. Наприклад, скажімо, наша add функція тепер приймає поплавці замість цілих чисел і що у нас не ввімкнено сувору перевірку типів:Тоді ми могли б викликати функцію так:

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

Відповідь, яку ми повинні були отримати,

echo add(1.25, 2.25);
 
// Output:
// 3
Did you spot the problem in the output?

- 3.5це . Однак, оскільки ми визначили тип повернення як int, ми перетворили поплавок (який повинен був бути повернутий) на ціле число і втратили точність. Як ви можете собі уявити, це може спричинити деякі проблеми в інших частинах нашої програми, де ми використовуємо цей результат, і точність, можливо, знадобилася.

Тепер давайте вирішимо цю проблему за допомогою declare(strict_types=1):Тоді ми могли б викликати функцію так:

declare(strict_types=1);
 
function add(float $a, float $b): int
{
    return $a + $b;
}
Відповідь, яку ми повинні були отримати,
echo add(1.25, 2.25);
 
// Output:
// Fatal error: Uncaught TypeError: add(): Return value must be of type int, float returned

Як ми бачимо, увімкнувши сувору перевірку типів, ми можемо помітити, що функція не повертає правильний тип даних. Це чудово, тому що це може висвітлити можливу помилку в нашому коді, про яку ми не знали. Тоді ми могли б зробити необхідні кроки, щоб:

  • Оновіть типи повернення, якщо вони неправильні
  • Оновіть підказки типу, якщо вони неправильні
  • Оновіть тіло функції, щоб повернути правильний тип даних, якщо він неправильний
  • Виправте будь-які помилки в коді, що викликає функцію, яка може передавати їй неправильний тип даних

Чи варто використовувати declare(strict_types=1)?

Особисто я вважаю, що це гарна ідея використовувати declare(strict_types=1) у всіх ваших файлах PHP. Раніше я думав, що достатньо лише підказок щодо типів типів і типів повернення, щоб забезпечити передачу правильних типів даних, але з тих пір я змінив свою думку. Я відчуваю себе набагато впевненіше в своєму коді, коли використовую declare(strict_types=1) і знайшов кілька помилок в результаті його використання (зокрема, при додаванні його до старих баз коду).

Дізнавшись про це, я взяв за звичку використовувати його в кожному новому файлі PHP, який я створюю. Фактично, я оновив усі шаблони в моєму налаштуванні PhpStorm таким чином, щоб він автоматично включався у верхню частину кожного файлу, який я створюю. Наприклад, ось шаблон, який використовується при створенні нового класу PHP: Це дійсно зручно,

 <?php
 
 declare(strict_types=1);
 
 #parse("PHP File Header.php")
 
 #if (${NAMESPACE})
 namespace ${NAMESPACE};

 #end
class ${NAME} {

}

тому що він заохочує мене продовжувати використовувати declare(strict_types=1) без необхідності вносити будь-які зміни вручну після створення файлу (що я точно забув би зробити!).

Для будь-якого з моїх читачів Laravel ви також можете опублікувати заглушки , які використовуються для створення файлів PHP при запуску команд Artisan, таких як php artisan make:controller. Публікуючи заглушки, ви можете редагувати їх і додавати declare(strict_types=1) вгору. Це означає, що файли, які ви створюєте за допомогою команд Artisan, будуть створені з більш суворою безпекою типів, які вже ввімкнено.

Звичайно, якщо ви збираєтеся додати суворішу перевірку типів до наявних файлів, я б настійно порадив спочатку створити якісний набір тестів. Можливо, ваш PHP-код дозволяв передавати неправильні типи даних, не допускаючи помилок. Але, увімкнувши сувору перевірку типу, ваш код стане набагато менш поблажливим і може почати викидати помилки. Це може призвести до того, що ваша програма зламається несподіваним чином для ваших користувачів.

Ви також можете виявити, що вам потрібно переробити частину вашого коду, щоб зробити його сумісним з declare(strict_types=1). Хоча я б не вважав це поганим. Замість цього я б розглядав це як можливість поліпшити якість вашого коду.

Щоб допомогти в процесі додавання declare(strict_types=1) до вашого коду, ви можете використовувати такий інструмент, як PHPStan, який може виявити ці типи невідповідностей для вас.

висновок

Сподіваємося, ця стаття дала вам короткий огляд того, що declare(strict_types=1) таке і як це може допомогти вам підвищити безпеку типу вашого PHP-коду.

Якщо вам сподобалося читати цю публікацію, я хотів би почути про неї. Так само, якщо у вас є якісь відгуки щодо покращення майбутніх, я також хотів би почути це.

Можливо, вам також буде цікаво переглянути мою електронну книгу на 220+ сторінок "Battle Ready Laravel", яка більш глибоко охоплює подібні теми.

Якщо ви зацікавлені в оновленні кожного разу, коли я публікую новий пост, не соромтеся підписатися на мій інформаційний бюлетень нижче.

Продовжуйте створювати чудові речі! 🚀

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297