declare
Ключевое слово declare — управляющая структура PHP для директив выполнения: strict_types, encoding и ticks.
Ключевое слово PHP declare
declare — управляющая структура PHP, которая устанавливает директиву выполнения для кода, которым она управляет. В отличие от большинства операторов, директива не выполняет логику — она изменяет способ интерпретации окружающего кода движком. PHP поддерживает ровно три директивы: strict_types (принудительная проверка объявлений типов), encoding (задаёт кодировку символов скрипта) и ticks (устаревший хук событий, удалённый в PHP 8.0).
Наиболее распространённая причина использовать declare сегодня — одна строка в начале файла: declare(strict_types=1);. На этой странице рассматриваются синтаксис, каждая директива и типичные ошибки, с которыми сталкиваются разработчики.
Синтаксис
Существует две формы. Форма оператора применяет директиву ко всему оставшемуся файлу:
declare(directive);Форма блока применяет директиву только к коду внутри фигурных скобок:
declare(directive) {
// code block
}Форма блока допустима только для ticks. Директивы strict_types и encoding должны использовать форму оператора и быть самым первым оператором в файле (перед ними может стоять только <?php). Использование формы блока со strict_types является фатальной ошибкой.
strict_types: принудительная проверка объявлений типов
По умолчанию PHP приводит скалярные аргументы к типам, объявленным в функции. При использовании declare(strict_types=1); этого не происходит — передача неверного типа вызывает TypeError. Именно эту директиву вы будете использовать в повседневной работе.
Два правила, которые нужно помнить:
- Это должен быть первый оператор в файле. Всё, что стоит перед ним — даже вывод пробелов или другой оператор — является фатальной ошибкой.
- Директива действует на уровне файла. Строгий режим применяется к вызовам, сделанным из этого файла, в зависимости от того, где находится вызов, а не где определена функция. Функция библиотеки, вызванная из строгого файла, проверяется строго; та же функция, вызванная из нестрогого файла, не проверяется.
Без этой директивы add(2, "3") молча приведёт "3" к 3 и вернёт 5 — именно такие скрытые ошибки strict_types и призван выявлять.
encoding: объявление кодировки символов скрипта
declare(encoding='ISO-8859-1');Это сообщает движку, как интерпретировать байты файла скрипта. В современных системах, где повсеместно используется UTF-8, эта директива редко нужна, но может иметь значение для устаревших файлов или специфических конфигураций сервера. Она имеет эффект только тогда, когда PHP скомпилирован с поддержкой многобайтовых строк.
ticks: устаревший хук событий
Тик — это событие, генерируемое каждые N низкоуровневых операторов, выполняемых внутри блока declare. Он использовался для добавления простых обратных вызовов (обработка сигналов, профилирование) к синхронному коду. Это единственная директива, для которой форма блока имеет смысл:
declare(ticks=1) {
function tick_handler() {
echo "tick" . PHP_EOL;
}
register_tick_function('tick_handler');
$a = 1;
$a += 2;
}Точное количество тиков зависит от числа выполненных операторов. Директива ticks была удалена в PHP 8.0 — не используйте её в новом коде; современные альтернативы включают pcntl_signal для обработки сигналов.
Когда использовать каждую директиву
strict_types=1— добавляйте в начало каждого нового файла. Это наиболее ценное применениеdeclareи практически универсальное соглашение в современном PHP. Смотрите PHP Data Types и PHP Functions для понимания того, как работают объявления типов.encoding— только когда у вас действительно есть файл с кодировкой, отличной от UTF-8, и скомпилирована поддержка многобайтовых строк.ticks— не используйте; директива удалена начиная с PHP 8.0.
Заключение
declare устанавливает директивы выполнения для скрипта. На практике это означает одну строку — declare(strict_types=1); — которая превращает молчаливое приведение типов в явные ошибки и делает сигнатуры функций значимыми. Директивы encoding и ticks относятся к узкоспециализированным и устаревшим случаям соответственно, но знание всех трёх позволяет избежать неожиданностей при выборе между формой оператора и формой блока.