Зачем использовать declare(strict_types=1) в PHP
В этой статье мы рассмотрим, что означает declare(strict_types=1)
, когда PHP разработчикам стоит его использовать, а когда нет, а также приведём примеры, иллюстрирующие его важность.
Такая установка обусловлена слаботипизированной природой PHP и растущим спросом на строго типизированные возможности, который предъявляют другие популярные языки, такие как Java.
Обе стратегии типизации (слабая и строгая) имеют свои плюсы и минусы, прежде всего, давайте разберёмся в их значении.
Слабо типизированный язык
Слабо типизированный язык, также известный как динамически типизированный язык, — это язык программирования, в котором переменные не привязаны к определённому типу данных во время компиляции. Не нужно заранее объявлять, какой тип данных будет у переменной во время выполнения.
Тип данных переменной определяется в зависимости от хранимого в ней значения и может изменяться во время выполнения программы.
PHP, по сути, является слабо типизированным языком, поэтому мы можем написать пример на нем:
$a = "hello";
$a = 1;
// Ошибок нет. Содержимое переменной изменяется со string на int.
Слабо типизированные языки часто допускают неявное приведение типов, то есть могут автоматически преобразовывать данные из одного типа в другой для облегчения выполнения операций. Такое поведение может привести к большей гибкости, но также и к большей вероятности функциональных ошибок.
Строго типизированный язык
Строго типизированный язык, также известный как статически типизированный язык, — это язык программирования, в котором переменные должны быть явно объявлены с определённым типом данных во время компиляции.
После того как тип данных переменной определён, он не может измениться в течение всего времени её существования. Строго типизированные языки не выполняют неявного приведения типов, поэтому операции между переменными разных типов обычно приводят к ошибке компиляции.
Мы можем написать пример на языке Java:
public class CompileError {
public static void main(String[] args) {
int x = 15;
x = "Valerio";
}
}
Что означает declare(strict_types=1)
declare(strict_types=1)
— это директива в PHP, обеспечивающая строгую проверку типов аргументов и возвращаемых значений функций и методов в конкретном PHP-файле или блоке кода. При включении строгой проверки типов PHP гарантирует, что типы данных аргументов и возвращаемых значений функций в точности соответствуют объявленным типам. Точно так же, как это делается в Java.
Поместите это объявление в самое начало вашего PHP-файла или блока кода (перед любым другим кодом), для включения строгой типизации.
Вот базовый синтаксис для включения строгой проверки типов:
<?php
declare(strict_types=1);
function speak(string $name): string
{
return "Hello {$name}!";
}
speak(1); // Выдаётся ошибка "Uncaught TypeError".
speak("Valerio"); // Выводится "Hello Valerio!".
Зачем использовать declare(strict_types=1)
Применение строгой типизации может значительно повысить надёжность кода в определённых сценариях.
Строгая типизация помогает предотвратить неожиданные проблемы, связанные с типами, которые могут привести к ошибкам во время выполнения программы или некорректному поведению. Она гарантирует, что вы всегда будете работать с теми типами данных, которые вы ожидаете.
Например, рассмотрим функцию, выполняющую сложение двух чисел:
function add($a, $b)
{
return $a + $b;
}
$result = add(5, '10'); // Без строгой типизации это допустимо.
echo $result; // Вывод: 15
Без строгой типизации PHP превратит строку '10' в целое число и выдаст результат, который может оказаться не тем, что вы задумали.
С declare(strict_types=1)
:
<?php
declare(strict_types=1);
function add(int $a, int $b)
{
return $a + $b;
}
$result = add(5, '10'); // Fatal error: Uncaught TypeError
При включении строгой типизации PHP выбрасывает TypeError
и предотвращает выполнение функции, обеспечивая безопасность типов.
Какую стратегию выбрать
Защита типов полезна в различных аспектах разработки программного обеспечения и может повысить надёжность и сопровождаемость кода. Но она не является святым Граалем.
Я настоятельно не рекомендую смешивать эти две стратегии. Не стоит активизировать такое поведение языка только в двух-трёх файлах. Это может только усложнить понимание причин возникновения ошибки, если в разных частях приложения код выполняется по разным правилам.
Если вы предпочитаете строгую типизацию, используйте её во всем коде. В противном случае современный PHP предлагает множество других средств для обеспечения явного объявления типа в коде. Вы имеете широкую поддержку объявления типов в аргументах функций, возвращаемых типах, свойствах классов, тройных равенствах и т.д.
Кроме того, работа с HTTP-запросами может быть неприятной при включённой строгой типизации, поскольку в HTTP-запросах все является строкой. Чтобы избежать лишней головной боли, создавайте тесты.