PHP 8.2: Главные нововведения

Практический обзор для перехода с PHP 8.1.x на 8.2.x: новые возможности языка, атрибуты для защиты секретов в трассировках, ужесточение работы со строками и таймзонами, плюс deprecations, которые лучше закрыть до следующего релиза.

Содержание (Оглавление)


PHP 8.2 продолжает курс на явность: readonly-классы, более выразительная система типов (DNF), атрибут #[SensitiveParameter] для редактирования чувствительных аргументов в backtrace. Параллельно ужесточается поведение ряда функций (ASCII-регистр без учёта locale у базовых строковых helper’ов, str_split(''), glob() при open_basedir) и объявляются устаревшими приёмы вроде динамических свойств без явного разрешения.

#[SensitiveParameter] и трассировки

Атрибут #[\SensitiveParameter] помечает параметры, которые нужно скрывать в stack trace и отладочном выводе — меньше риска утекания паролей и токенов в логи.

function connect(#[\SensitiveParameter] string $password): void
{
    throw new RuntimeException('fail');
}

Сочетайте с политикой логирования и не выводите сырые исключения пользователям в production.

Практический рецепт: отмечайте секреты на границе

Ставьте #[\SensitiveParameter] на параметры, которые могут оказаться в исключениях (обёртки клиентов, auth‑хелперы). Stack trace остаётся полезным, но секреты не «просачиваются» в логи.

final class ApiClient
{
    public function __construct(
        private readonly string $baseUrl,
        #[\SensitiveParameter] private readonly string $token,
    ) {}
}

Readonly-классы

Класс можно объявить readonly: все его свойства экземпляра становятся readonly и задаются при конструировании.

readonly class Point
{
    public function __construct(
        public int $x,
        public int $y,
    ) {}
}

Удобно для иммутабельных value object и DTO, где объект целиком не должен меняться после создания.

Отдельные типы (null, false, true) и DNF

В PHP 8.2 null, false, true допустимы как самостоятельные типы в объявлениях.

DNF позволяет комбинировать union и intersection в нормализованной форме, например (A&B)|null.

function accepts((Countable&Traversable)|null $c): void {}

Константы в трейтах и enum в константных выражениях

  • В трейтах можно объявлять константы — удобно для общих значений без лишнего базового класса.
  • В константных выражениях разрешено обращаться к свойствам enum там, где это предусмотрено синтаксисом — богаче конфигурация на этапе компиляции.

INI: error_log_mode

Директива error_log_mode задаёт права файла error log при создании PHP — полезно для жёстко настроенных серверов.

Расширение Random

Расширение Random систематизирует генераторы случайных чисел и даёт более предсказуемый API для тестов и криптографически осмысленных сценариев.

Практический рецепт: Randomizer для токенов и выборки

$engine = new Random\Engine\Mt19937(random_int());
$randomizer = new Random\Randomizer($engine);
$token = $randomizer->getBytesFromString('0123456789abcdef', 32);

В тестах задавайте seeded engine для воспроизводимости; для секретов выбирайте криптографически подходящий Random\Engine по документации.

Заметные изменения расширений (cURL, PCRE)

  • cURL: CURLINFO_EFFECTIVE_METHOD, функция curl_upkeep(), новые константы при поддерживаемой libcurl.
  • PCRE: модификатор n (NO_AUTO_CAPTURE) — обычные () не захватывают, только именованные группы.

Обратно несовместимые изменения (миграционные заметки)

Дата и время

  • У DateTime::createFromImmutable() / DateTimeImmutable::createFromMutable() — tentative return type static.
  • В относительных форматах больше не допускается несколько знаков в number (например +-2).

Стандартная библиотека (важно)

  • **strtolower/strtoupper/stri*/str_ireplace/lcfirst/ucfirst/ucwords**: **не locale-sensitive** — только ASCII, как "C"`. Локализованный регистр — через mbstring.
  • str_split('') теперь возвращает [] (раньше был массив с одной пустой строкой).
  • glob() / GlobIterator: при open_basedir изменилось поведение [] vs false и предупреждения — проверьте обход каталогов.
  • FilesystemIterator: SKIP_DOTS больше не включён по умолчанию через флаги — задайте явно при необходимости.
  • ksort/krsort с SORT_REGULAR — согласованные правила числовых строк PHP 8.
  • var_export(): имена классов экспортируются с ведущим обратным слэшем (полностью квалифицированные).

ODBC / PDO_ODBC

Экранирование username/password при дописывании к connection string — проверьте интеграции.

SPL

У части методов SplFileObject ужесточены сигнатуры; у hasChildren/getChildren — уточнены tentative return types.

Замечание: в некоторых окружениях date_default_timezone_get() при отсутствии явной зоны может возвращать UTC — проверьте предположения о таймзоне.

Deprecated (исправить до появления ошибок)

Динамические свойства

Создание динамических свойств у классов без объявления — deprecated, если класс не помечен #[\AllowDynamicProperties] (или не stdClass и т. п.). Лучше объявить свойства, использовать WeakMap или магические методы.

«Относительные» callables

Устарели формы вроде "self::method", часть массивных callables — приведите к стабильным Class::method / [Class::class, 'method'].

Интерполяция строк

Стиль "${var}" — deprecated; используйте "{$var}" или конкатенацию.

Прочее

  • utf8_encode / utf8_decode — deprecated.

Расширения и runtime

  • OpenSSL: AEAD для chacha20-poly1305 при наличии поддержки.
  • OCI8: настройка prefetch LOB для Oracle 12.2+.
  • DBA (LMDB): флаги подкаталога при создании БД.

Итог

PHP 8.2 выгоден тем, кто явно моделирует данные: readonly-классы, точные типы, меньше утечек через #[SensitiveParameter], и раннее устранение deprecated вокруг динамических свойств. Отдельно проверьте строки/регистр, open_basedir и таймзону после апгрейда.