Type Hinting. Описание типов

Бывает что код используется не так как нам хотелось бы:

<?php

function sayHelloTo($name)
{
print_r("Hello, {$name}");
}

Функция выше, ожидает на вход строку. Это видно по тому, как используется переменная $name. А что, если мы ошибемся и передадим массив? :

<?php

//  передается не то, что ожидается:
sayHelloTo([]);
// PHP Notice:  Array to string conversion

Благодоря динамической типизации языка код отработает, но результат не будет соответствовать нашим ожиданиям. Но можно тех местах, где входной тип особенно важен, добавить соответствующую проверку и генерировать исключение, если переданы неверные данные. Так делали раньше, до введения в язык type hinting.

Type Hinting - это механизм, который позволяет явно указывать типы параметров. Интерпретатор использует их в своей работе и возбуждает исключение в тех ситуациях, когда тип не соответствует ожидаемому.

По крайней мере, это так работает в большинстве языков, где присутствует данный механизм. В PHP все чуть сложнее и хуже из-за слабой типизации. Несмотря на то, что можно жестко указать тип int, это не значит, что интерпретатор начнет ругаться на все остальное. Он спокойно проглотит и логический тип и строковый.

Чтобы объявить тип аргумента, необходимо перед его именем добавить имя требуемого типа:

<?php

// string указывает на то, что тип аргумента - строка:
function sayHelloTo(string $name)
{
print_r("Hello, {$name}");
}

sayHelloTo([]);
// PHP Fatal error:  Uncaught TypeError: Argument 1 passed to sayHelloTo() must be of the type string, array given

Теперь ошибка совсем другая - нам явно говорят о том, что типы не сошлись. Увидеть и исправить подобную ошибку уже значительно легче. Рассмотрим еще один пример - с несколькими аргументами:

<?php

function get(string $text, int $index, $default = null)
{
return isset($text[$index]) ? $text[$index] : $default;
}

get('hi', 3, 8); // 8

get('ho', 'hey');
// TypeError: Argument 2 passed to get() must be of the type integer, string given

Null не похож на другие типы данных и ведет себя особым образом. Типы данных в PHP не являются nullable, это значит, что если мы ждем на вход значение определенного типа, например, строку, то этим значением не может быть Null, но, если указать значение, по умолчанию равное Null, то указанный тип становится nullable и появится возможность передавать Null снаружи.

Не nullable

<?php

function printStr(string $value)
{
echo $value;
}
printStr(null);
// Fatal error: Uncaught TypeError: Argument 1 passed to printStr() must be of the type string, null given

nullable

<?php

function printStr(string $value = null)
{
echo $value;
}
printStr(null);

С версии PHP 7.2 появилась возможность указывать тип не только для входящих параметров, но и для возврата функции. Оно записывается через двоеточие после закрывающей скобки:

<?php

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

Если ошибиться в теле функции выше и вернуть строку, то интерпретатор скажет об этом:

TypeError: Return value of sum() must be of the type integer, string returned