Система типов
PHP долго был языком без типов: в функцию можно было передать что угодно. Сегодня типы указывают для параметров, результатов и свойств. Ошибка, которая раньше всплывала через неделю у пользователя, теперь обнаруживается в момент вызова.
Типы параметров и результата
<?php
function repeat(string $text, int $times): string
{
return str_repeat($text, $times);
}
echo repeat('ab', 3); // abababЕсли передать значение неподходящего типа, PHP выбросит ошибку TypeError.
Строгий режим
По умолчанию PHP пытается преобразовать значение: строка '5' превратится в число. Директива strict_types это запрещает. Она пишется первой строкой файла:
<?php
declare(strict_types=1);
function double(int $number): int
{
return $number * 2;
}
try {
echo double('5');
} catch (TypeError $error) {
echo 'Нужно целое число';
}Без директивы функция молча вернула бы 10. В новых проектах строгий режим включают в каждом файле.
Значение или null
Знак вопроса перед типом разрешает null:
<?php
function findUser(int $id): ?string
{
return $id === 1 ? 'Анна' : null;
}
echo findUser(1) ?? 'не найден', "\n"; // Анна
echo findUser(2) ?? 'не найден'; // не найденОбъединённые типы
Вертикальная черта перечисляет допустимые типы:
<?php
function formatId(int|string $id): string
{
return is_int($id) ? '#' . $id : strtoupper($id);
}
echo formatId(7), ' ', formatId('ab-1'); // #7 AB-1Запись ?string — то же самое, что string|null.
void и never
void означает, что функция ничего не возвращает. never — что она вообще не возвращает управление: всегда выбрасывает исключение или завершает программу:
<?php
function logMessage(string $message): void
{
echo '[log] ', $message, "\n";
}
function fail(string $message): never
{
throw new RuntimeException($message);
}
logMessage('Старт');
try {
fail('Стоп');
} catch (RuntimeException $error) {
echo $error->getMessage(); // Стоп
}Типизированные свойства
Тип указывают и у свойств класса. Присвоить значение другого типа не получится:
<?php
class Product
{
public function __construct(
public string $title,
public int $price,
public ?string $description = null,
) {}
}
$product = new Product('Чай', 250);
echo $product->title, ' ', $product->price, ' ', $product->description ?? 'без описания';Основные типы
| Тип | Значения |
|---|---|
int, float, string, bool | Простые значения |
array | Массив |
callable | Функция |
iterable | Массив или объект, который можно перебрать |
mixed | Любое значение |
self, static | Текущий класс |
| Имя класса или интерфейса | Объект этого типа |
Частая ошибка
Тип array ничего не говорит о содержимом массива. Функция, которая ждёт список чисел, примет и массив строк. Проверяйте содержимое сами или описывайте его в комментарии над функцией — редактор учитывает такие подсказки:
<?php
/**
* @param int[] $numbers
*/
function total(array $numbers): int
{
return array_sum($numbers);
}
echo total([1, 2, 3]); // 6