Типизация аргументов и свойств в PHP 7 и 8

2020-08-28 14:59:15


С каждой версией язык php обрастает новыми возможностями, делая жизнь разработчиков проще. В этой статье мы обсудим возможности типизации в современных версиях PHP и преимущества использования типов.

Типизация в PHP

В языке PHP динамическая типизация. Это значит, что при инициализации переменной ей нельзя назначить тип. Тип переменной выставиться динамически в зависимости от значения (или результат выполнения выражения), которое ей присваивается. Он может меняться в процессе выполнения скрипта. Продемонстрирую на примере:

<?php

// Инициализируем переменную, присвоив ей целочисленное значение
$myVar = 15;
var_dump($myVar); // выведет int(15)

// А теперь преобразуем тип в строковый
$myVar = (string)$myVar;
var_dump($myVar); // выведет string(2) "15"

// Прибавим к строке число
// php автоматически преобразует строковое значение к целочисленному
$myVar = $myVar + 5;
var_dump($myVar); // выведет int(20)

// А теперь добавим к числу строку
// в результате чего php преобразует исходное значение в строку
$myVar = $myVar . ' яблок';
var_dump($myVar); // выведет string(13) "20 яблок"

Для справки: есть языки программирования со статической типизацией. В них при инициализации переменной нужно обязательно указывать тип. В случае, если переменной будет присваиваться значение типа, отличного от указанного, то компилятор сообщит об ошибке.

Типизация аргументов в функциях и методах

В последних версиях PHP появился возможность указывать типы для аргументов функций и возвращаемого ею значения. Рассмотрим эти возможности на примере:

<?php

// Включаем строгую типизацию
declare(strict_types=1);

function myTestOperation(int $firstParam, string $secondParam, array $thirdParam) : bool
{
    // ...

    return true;
}

// Вызываем функцию
myTestOperation(123, 'test', [4, 5, 6]);

Код содержит функцию с 3 аргументами различных типов. Типы указываются перед именем аргумента, а тип возращаемого значения после двоеточия.

Обратите внимание на строку «declare(strict_types=1);» Она включает строгую типизацию. Например, если при строгой типизации мы передадим в первый аргумент функции строку вместо числа, то получим ошибку:

TypeError: Argument 1 passed to myTestOperation() must be of the type int, string given

Если удалить строчку declare(strict_types=1), PHP попытается преобразовать переданную строку в число. Если преобразовать невозможно, PHP выбросит исключение TypeError.

Типы аргументов и тип возвращаемого значения могу быть следующими:

  • int - целочисленный тип;
  • float - числа с плавающей точкой (десятичная дробь);
  • string - строка;
  • array - массив;
  • callable - callback-функция;
  • имя класса - в качестве аргумента должен передаваться экземпляр класса;
  • интерфейс - в качестве аргумента должен передаваться класс, имплементирующий (реализующий) данный интерфейс.

Null и void в сигнатуре функции

В случае, если функция или метод класса не возвращают значение, после двоеточия пишется ключевое слово void.

function myAction(): void 
{
    // ...
    // В функции не должно быть return
}

В случае, если какие-то из аргументов функции мы захотим сделать необязательными, на нужно добавить знак ? перед именем типа. Это правило работает и для возвращаемого значения. Например, для аргумента ?int $myVar можно передать значение либо null, либо целое число. Чтобы явно не передавать null в качестве значения необязательного аргумента, обычно в сигнатуре присваивают значение по умолчанию, как показано в следующем примере:

function myTestOperation(int $firstParam, ?string $secondParam = null, ?array $thirdParam = null): ?float
{
    var_dump($firstParam); // выведет int(6)
    var_dump($secondParam); // выведет NULL
    var_dump($thirdParam); // выведет NULL

    return null; // Можно венруть null, так как в сигнатуре ?float (либо десятичная дробь, либо null)
}

// Вызываем функцию
// Явно передаем null во 2 и 3 аргументы
myTestOperation(6, null, null);

// Вызываем еще раз
// При этом не передаем необязательные аргуметы, так как в сигнатуре присвоены дефолтные значения
// При этом результат выполнения будет идентичен
myTestOperation(6);

Преимущества указания типов в PHP

Использование типов и строгой типизации дает на следующие преимущества:

  • снижает риск ошибок, связанными с типами;
  • выполняет функцию документации - то есть мы видим: какого типа данные нужно передавать в качестве аргумента в функцию;
  • заставляет вас правильно проектировать функцию, не позволяя принимать аргументы и возвращать значения разных типов.

Типизация свойств объекта в PHP 7.4

В PHP версии 7.4 появилась возможность указывать типы в классах.

<?php

class MyClass
{
    private string $myParamOne;
    private int $myParamTwo;
    private array $myParamThree;
    private Object $myParamFour;
}