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

Минор PHP 7.1 превращает типы из «эксперимента» в рабочий инструмент: появляются nullable-объявления ?T, возвращаемый тип void, псевдотип iterable, модификаторы доступа у констант класса, расширенный list() (в том числе с ключами), несколько типов в одном catch и удобный Closure::fromCallable().

Параллельно движок становится менее терпимым к «кривым» вызовам: если у пользовательской функции не хватает обязательных аргументов, вместо предупреждения вылетает ArgumentCountError. Отдельно стоит пересмотреть код, где строки подсовывали под массивы через [], конфигурацию session-директив и тесты, завязанные на побайтовое равенство двух «только что созданных» DateTime.

Оглавление


Nullable-типы (?T)

Запись ?User означает «User или null» — и для параметров, и для возвращаемого значения. Пустой return; при не-void типе по-прежнему ошибка: нужен return null; или конкретный объект.

function findUser(?int $id): ?User {
    return $id === null ? null : User::load($id);
}

Возвращаемый тип void

Подходит для функций, которые ничего осмысленного не возвращают (только побочный эффект). Разрешён return; без выражения; return 42; уже нарушение контракта.

Псевдотип iterable

Объединяет массивы и любые объекты с Traversable — единая сигнатура для «то, по чему можно пройтись foreach».

Видимость констант класса

Константы, как и свойства, можно помечать public, protected или private, чтобы сузить контракт класса.

list() с ключами и короткая деструктуризация

Появляется возможность забирать элементы по ключам, а также короткая форма [$a, $b] = $tuple — меньше шума, чем длинные list(...) в обработчиках конфигов и пар (ключ, значение).

Multi-catch

try {
    // …
} catch (NetworkException | TimeoutException $e) {
    // общий путь восстановления
}

Другие заметные новшества

  • Closure::fromCallable() оборачивает произвольный callable в полноценный Closure.
  • Для сигналов: pcntl_async_signals(); для cURL: curl_multi_errno(), curl_share_errno() и другие мелочи — полный список в migration71 new-features.

Практические рецепты

Явные необязательные параметры вместо «недозвона»

function save(User $user, bool $flush = false): void { /* … */ }

Если параметр обязателен — не рассчитывайте на предупреждение: теперь это ArgumentCountError.

Nullable + значение по умолчанию в строке

function label(?string $s): string {
    return $s ?? 'default';
}

Обратно несовместимые изменения

Число аргументов

  • У пользовательских функций и методов нехватка аргументов → ArgumentCountError (раньше было E_WARNING). Встроенные функции в основном сохраняют прежнюю модель — проверяйте обёртки, которые «глотали» warning.

Session INI

  • Удалены session.entropy_file, session.entropy_length, session.hash_function, session.hash_bits_per_character — идентификатор сессии больше не строится через этот конвейер (см. RFC по генерации session ID).

Массивы, ссылки, сортировки

  • Порядок автоматически созданных элементов при цепочках ссылок может отличаться от PHP 7.0 (в типичных кейсах ближе к PHP 5 — сверяйтесь с мануалом).
  • Алгоритмы сортировки могут по-разному упорядочивать равные с точки зрения компаратора элементы — не закладывайтесь на стабильность «ничьих».

Строки против массивов

  • Конструкции вроде $s[] = 'x', где $s — строка, и прочие трюки «строка ведёт себя как массив» запрещены. Запись по числовому смещению в строке следует байтовой семантике — см. примеры в мануале и комментарии пользователей к migration guide.

Сериализация и время

  • Второй аргумент unserialize(): поле allowed_classes должно быть массивом или bool — иначе false и предупреждение.
  • DateTime / DateTimeImmutable, созданные «с нуля» или относительной строкой, включают микросекунды — наивное == двух свежих объектов чаще ложно.

JSON, mbstring, TLS

  • С флагом JSON_UNESCAPED_UNICODE символы U+2028 и U+2029 экранируются.
  • У mb_ereg() / mb_eregi() третий аргумент ($regs) становится пустым массивом, если совпадения не было.
  • Поток sslv2 в OpenSSL убран.

Замыкания

  • Переменные в use не могут называться как суперглобалы, $this или как параметры функции.

Расширения: fatal → Error

Длинный перечень DOM, Intl, mysqli, сессий, SimpleXML, SPL, Zip и др. — в migration71 incompatible. Готовьтесь, что «раньше был recoverable fatal» теперь Error.

Deprecated

  • Расширение mcrypt помечено устаревшим (в 7.2 его вынесли из ядра) — планируйте OpenSSL / Sodium.
  • Модификатор e в mb_ereg_replace() / mb_eregi_replace() (eval-подстановка) объявлен deprecated.

Прочие изменения

  • Арифметика с некорректными числовыми строками теперь сопровождается notice/warning.
  • Переполнение восьмеричных escape-последовательностей в строках даёт предупреждение.

Итог

PHP 7.1 — это «типизированный PHP, который можно продавать продакту»: nullable, void и iterable упрощают контракты, но ArgumentCountError и правки строк/смещений вскроют долги эпохи PHP 5. Закройте арность и строки до того, как накроет волна предупреждений count() в 7.2.