> Расскажите про типизацию в PHP (PHP)
Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы
Компании: vanta
Стек: PHP
> Пример ответа
Короткий ответ
PHP - язык с динамической типизацией, но с 7-й версии активно развивается строгая типизация через декларации типов. Ключевые механизмы: type hints для параметров и возвращаемых значений, strict_types для контроля приведения, union types, nullable types, mixed, а также типизированные свойства классов. В PHP 8 появились intersection types, static return type и атрибуты для метаданных. На практике это даёт баланс между гибкостью динамики и безопасностью статики.
Подробное объяснение
Типизация в PHP прошла долгий путь: от полностью динамической в PHP 5 до гибридной в PHP 8.x. Основная идея - не заставлять разработчика указывать типы везде, но дать возможность явно контролировать контракты между функциями и классами.
Механизмы типизации:
- Type hints - для параметров функций/методов и возвращаемых значений. Поддерживаются скалярные типы (int, float, string, bool), классы, интерфейсы, callable, iterable, object, mixed (PHP 8.0).
- strict_types=1 - директива в начале файла, которая запрещает неявное приведение скалярных типов. Без неё PHP пытается привести значение (например, "123" → int 123), с ней - выбрасывает TypeError.
- Union types (PHP 8.0) - параметр или возврат может принимать несколько типов:
int|string. - Intersection types (PHP 8.1) - тип должен удовлетворять нескольким классам/интерфейсам:
A&B. - Nullable types -
?TypeилиType|null. - Типизированные свойства (PHP 7.4) -
public int $count;с обязательной инициализацией или readonly. - Readonly свойства (PHP 8.1) - неизменяемые после инициализации.
- mixed - любой тип, эквивалент отсутствия типа, но явный.
- never (PHP 8.1) - функция не возвращает управление (exit, throw).
- static (PHP 8.0) - возврат типа вызывающего класса (позднее статическое связывание).
Важный нюанс: strict_types действует только на вызовы из файла, где она объявлена. То есть если файл A вызывает функцию из файла B, то поведение приведения определяется директивой в файле A.
Типизация в PHP - это не статический анализ, а runtime-проверка. Она не ловит ошибки до выполнения, но гарантирует корректность в момент вызова. Для статического анализа используются инструменты вроде Psalm или PHPStan, которые работают поверх синтаксиса и аннотаций.
На практике
В реальных проектах типизация применяется для:
- Контрактов между сервисами и репозиториями - каждый метод явно объявляет, что принимает и возвращает.
- DTO и Value Objects - типизированные свойства защищают от "мусорных" данных.
- API-слоёв - строгие типы предотвращают случайное приведение строк к числам.
- Работы с коллекциями - generic-аннотации (@param User[] $users) для статических анализаторов, хотя runtime их не проверяет.
Рекомендации:
- Всегда включать
declare(strict_types=1)в новых файлах - это дисциплинирует и убирает неявные приведения. - Использовать union types вместо
mixedтам, где это возможно. - Для свойств классов - типизировать и инициализировать, избегая
nullбез необходимости. - Для сложных структур (массив объектов) - комбинировать runtime-типы с PHPDoc для статических анализаторов.
- Не злоупотреблять
mixed- это фактически отказ от типизации.
Пример кода
PHP<?phpdeclare(strict_types=1);final class User{public function __construct(public readonly int $id,public readonly string $name,public readonly ?string $email = null,) {}}interface UserRepository{/** @return list<User> */public function findByName(string $name): array;public function findById(int $id): ?User;}final class UserService{public function __construct(private UserRepository $repository,) {}public function getUserLabel(int|string $identifier): string{$user = is_int($identifier)? $this->repository->findById($identifier): $this->repository->findByName($identifier)[0] ?? null;if ($user === null) {throw new RuntimeException('User not found');}return sprintf('%s (%d)', $user->name, $user->id);}}
Как отвечать на собеседовании
Начните с краткого определения: PHP - динамически типизированный язык с возможностью строгой типизации на уровне runtime. Затем перечислите ключевые механизмы в хронологическом порядке: PHP 7 - скалярные типы и strict_types, PHP 7.4 - типизированные свойства, PHP 8 - union types, mixed, static, PHP 8.1 - intersection types, readonly, never.
Обязательно упомяните разницу между strict_types=1 и поведением по умолчанию - это частый вопрос. Приведите пример: без strict_types "123" приведётся к int, с - выбросит TypeError.
Покажите понимание ограничений: типизация не проверяет структуру массивов, generic-типы не поддерживаются на уровне runtime, для статического анализа нужны Psalm/PHPStan. Это покажет зрелость мышления.
Если спросят про mixed - скажите, что это явный "любой тип", но лучше использовать union types, чтобы сохранить информацию для анализаторов.
Что проверяет интервьюер
- Понимание разницы между динамической и статической типизацией в контексте PHP.
- Знание конкретных синтаксических конструкций и их версий.
- Понимание поведения strict_types и области её действия.
- Умение объяснить trade-off между гибкостью и безопасностью.
- Осведомлённость о смежных инструментах (PHPStan, Psalm) и их роли.
Типичные ошибки
- Утверждение, что PHP - строго типизированный язык. Это не так: типизация опциональна и проверяется в runtime.
- Путаница между
strict_typesи type hints - это разные вещи: hints - декларация, strict_types - режим приведения. - Забывают, что strict_types действует на файл вызова, а не на файл определения.
- Использование
mixedкак "ленивого" решения без попытки сузить типы. - Незнание, что типизированные свойства требуют инициализации до чтения (иначе Error).
- Утверждение, что PHP поддерживает generics - это не так, только аннотации для статических анализаторов.
- Путаница между
?TypeиType|null- это одно и то же, но?Typeнельзя комбинировать с union types (нужно писатьType|null).
> Похожие задачи по PHP
В чем отличие массивов в PHP от массивов в других языках
Что происходит при несовпадении типов и как происходит проверка типов в PHP
Что происходит в контроллере после получения запроса
Что такое принцип подстановки Лисков из SOLID?
> Похожие задачи по backend
В чем отличие массивов в PHP от массивов в других языках
Что происходит при несовпадении типов и как происходит проверка типов в PHP
Что происходит в контроллере после получения запроса
С какими эволюционными базами данных ты работал
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью