Что нового в пхп 8
PHP 8 — пробуем новые возможности
Добавлена поддержка типов union (RFC)
Тип union принимает значения разных других типов, а не только какого-то одного.
Добавлены WeakMap (RFC)
Слабые карты (weak maps) позволяют создавать связи между объектами и произвольными значениями (как и SplObjectStorage ), при этом объекты, используемые в качестве ключей, не защищаются от сборщика мусора. Если сборщик уничтожает такой объект, тот просто удаляется из карты.
Это очень полезная фича. Она позволяет нам ещё меньше думать об утечках памяти в коде. Хотя для большинства PHP-разработчиков это не должно быть проблемой, но стоит обращать внимание при создании долгоиграющих процессов, например, используя ReactPHP. С WeakMaps ссылки на объекты автоматически собираются сборщиком мусора, когда объект становится недоступен.
Если вы сделаете то же самое с массивом, то ссылки на объект сохранятся, что приведёт к утечке памяти.
Новое исключение ValueError
При определении функций можно использовать вариативный аргумент
Вариативным аргументом теперь можно заменить любое количество параметров функции, если их типы совместимы. Например, следующий код некорректен:
Возвращаемый тип static (RFC)
Возвращаемый тип static теперь можно использовать для определения ситуации, что метод возвращает класс, для которого этот метод и был вызван, даже если он был унаследован (позднее статическое связывание).
Литерал имени класса для объекта (RFC)
Настройки синтаксиса переменных (RFC)
Интерфейс Stringable (RFC)
Теперь трейты могут определять абстрактные приватные методы (RFC)
throw теперь можно использовать как выражение (RFC)
Выражение throw теперь можно использовать там, где допускаются только выражения: в стрелочных функциях, coalesce-операторах тернарных условных операторах (ternary/elvis).
В параметрах списка теперь допускается опциональная висящая запятая (RFC)
По аналогии с висящей запятой в массивах, теперь можно определять её и в параметрах списка.
Ловля исключений без сохранения в переменной (RFC)
Теперь можно писать catch (исключение) для ловли исключений без их сохранения в переменной.
Добавлена поддержка типа mixed (RFC)
В PHP 8 появился новый тип mixed. Он может быть эквивалентен типам array, bool, callable, int, float, null, object, resource, string.
Добавлена поддержка атрибутов
Есть несколько предложений по внедрению атрибутов в PHP 8:
Чтобы было понятнее, представим, что вашим пользователям нужно дать возможность добавлять промежуточное ПО в контроллер класса или метода с помощью использования атрибута.
Добавлена поддержка продвижения свойств конструктора (RFC)
Предложено добавить простой синтаксис, позволяющий комбинировать конструктор с определением свойств:
Добавлена поддержка выражения match (RFC)
Добавлена поддержка оператора nullsafe (?->) (RFC)
Добавлена поддержка именованных аргументов (RFC)
Именование позволяет передавать аргументы функции в зависимости от имени параметра, а не от его позиции. То есть значения аргументов становятся самодокументирующимися, а аргументы перестают зависеть от порядка перечисления, поэтому можно произвольно пропускать значения по умолчанию.
PHP 8: код «До» и «После» (сравнение с PHP 7.4)
Осталось всего несколько месяцев до выхода PHP 8, и в этой версии действительно есть много хорошего. Под катом расскажем, как эти нововведения уже начали менять подход автора этого материала к написанию кода.
Подписчики событий с атрибутами
Я постараюсь не злоупотреблять атрибутами, но в случае с настройкой слушателей событий, например, они очень даже кстати.
В последнее время я работал над системами, где такой настройки было очень много. Возьмём пример:
У атрибутов в PHP 8 есть два преимущества:
Static вместо doc-блоков
Это не такое важное изменение, но я сталкиваюсь с этим каждый день. Я часто обнаруживаю, что мне всё ещё нужны doc-блоки, когда нужно указать, что функция имеет возвращаемый тип static.
Если в PHP 7.4 мне нужно было писать:
То теперь достаточно:
DTO, передача свойств и именованных аргументов
Я довольно много писал об использовании системы типов PHP и паттерна DTO (data transfer objects). Естественно, я часто использую DTO в своём собственном коде, поэтому можете представить, насколько я счастлив, что теперь имею возможность переписать это:
Обратите внимание на использование передачи свойств конструктора как именованных параметров. Да, их можно передавать с помощью именованных массивов и оператора Spread.
Перечисления и match
Вы используете перечисление с некоторыми методами, которые возвращают результат в зависимости от конкретного значения из перечисления?
Я бы сказал, что для более сложных условий вам лучше использовать паттерн Состояние, но есть случаи, когда достаточно перечисления. Этот странный синтаксис массива уже является сокращением для более громоздкого условного выражения:
PHP 7.4 — альтернативный вариант
Но в PHP 8 вместо этого мы можем использовать match.
Объединения вместо doc-блоков
Это работает аналогично тому, что было описано ранее для возвращаемого типа static.
Генерация исключений
Раньше вы не могли использовать throw в выражении, а это означало, что вам приходилось писать, например, вот такие проверки:
В PHP 8 throw стало выражением, что означает, что вы можете использовать его вот так:
Оператор nullsafe
Если вы знакомы с оператором null coalescing (коалесцирующий), вам известны его недостатки: он не работает с вызовами методов. Поэтому мне часто были нужны промежуточные проверки или подходящие для этой цели функции фреймворков:
С появлением оператора nullsafe я могу решить эту задачу гораздо проще.
А какие нововведения в PHP 8 считаете важными вы?
На правах рекламы
Серверы для разработки и размещения ваших проектов. Каждый сервер подключён к защищённому от DDoS-атак каналу в 500 Мегабит, есть возможность использовать высокоскоростную локальную сеть. Мы предлагаем большой выбор тарифных планов, смена тарифа в один клик. Очень удобная панель управления серверами и возможность использовать API. Поспешите проверить!
Что нового в пхп 8
Вместо аннотаций PHPDoc вы можете использовать структурные метаданные с нативным синтаксисом PHP.
Объявление свойств в конструкторе RFC Документация
Меньше шаблонного кода для определения и инициализации свойств.
Тип Union RFC Документация
new Number ( ‘NaN’ ); // Нет ошибки
new Number ( ‘NaN’ ); // TypeError
Вместо аннотаций PHPDoc для объединённых типов вы можете использовать объявления типа union, которые проверяются во время выполнения.
Выражение Match RFC Документация
Новое выражение match похоже на оператор switch со следующими особенностями:
Оператор Nullsafe RFC
Вместо проверки на null вы можете использовать последовательность вызовов с новым оператором Nullsafe. Когда один из элементов в последовательности возвращает null, выполнение прерывается и вся последовательность возвращает null.
Улучшенное сравнение строк и чисел RFC
При сравнении с числовой строкой PHP 8 использует сравнение чисел. В противном случае число преобразуется в строку и используется сравнение строк.
Ошибки согласованности типов для встроенных функций RFC
strlen ([]); // Warning: strlen() expects parameter 1 to be string, array given
strlen ([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given
Большинство внутренних функций теперь выбрасывают исключение Error, если при проверке параметра возникает ошибка.
Компиляция Just-In-Time
PHP 8 представляет два механизма JIT-компиляции. Трассировка JIT, наиболее перспективная из них, на синтетических бенчмарках показывает улучшение производительности примерно в 3 раза и в 1,5–2 раза на некоторых долго работающих приложениях. Стандартная производительность приложения находится на одном уровне с PHP 7.4.
Относительный вклад JIT в производительность PHP 8
Улучшения в системе типов и обработке ошибок
Прочие улучшения синтаксиса
Новые классы, интерфейсы и функции
Выше производительность, лучше синтаксис, надежнее система типов.
Для загрузки исходного кода PHP 8 посетите страницу downloads. Бинарные файлы Windows находятся на сайте PHP для Windows. Список изменений представлен в ChangeLog.
Руководство по миграции доступно в разделе документации. Пожалуйста, изучите его для получения подробного списка новых возможностей и обратно несовместимых изменений.
От версии 8 к 8.1: новый виток развития PHP
Я уже несколько раз писал о том, что происходило с PHP за год и всегда с нетерпением ждал следующего года. Я делал это в 2020-м и 2019-м. И продолжаю делать в 2021-м.
Я всегда повторяю: PHP это уже не тот язык, которым он был десять лет назад, и мы очень этому рады. Сегодня это быстрый и надёжный язык, позволяющий разрабатывать сложные и масштабируемые приложения. Давайте обсудим некоторые из наиболее заметных изменений, которые появились за год — как в самом языке, так и в экосистеме.
От версии 8 к 8.1
Новая мажорная версия PHP 8 появилась в конце прошлого года. Я уже много об этом писал, так что не буду здесь повторяться. Как всегда, его производительность становится всё лучше и лучше. Этот факт подтверждают тесты от Kinsta.
Во многом, это заслуга компилятора JIT (Just in time, «на лету»). Он действительно улучшает производительность (что особенно справедливо для математических операций). Но счастье было бы не полным, если бы ранее в PHP 7.4 не появилась предзагрузка. Она компилирует исходные файлы в опкоды и связывает зависимые классы, трейты и интерфейсы. Такой «скомпилированный» фрагмент исполняемого кода (то есть кода, который может использовать PHP-интерпретатор) сохраняется в памяти и становится доступен для всех запросов. Это положительно влияет на производительность, если вы, конечно, не используете виртуальный хостинг.
Стоит также упомянуть атрибуты (они же «аннотации»), именованные параметры (Named Arguments) и объявление свойств в конструкторе (Constructor Property Promotion), поскольку они определённо способствовали тому, что 8-я версия PHP получилась настолько удачной.
Не останавливаясь на достигнутом, PHP Core Team уже работает над следующей версией, PHP 8.1, которая должна выйти к концу 2021 года. На данный момент больше всего заслуживают внимания перечисления (enums) и файберы (fibers, зелёные потоки). Я ещё буду говорить о них позже в этой статье.
Год за годом команда выдаёт стабильные версии с множеством фич и других нововведений, улучшающих жизнь PHP-разработчикам. Среди прочего, в этот раз был усовершенствован процесс миграции. Я достаточно быстро перетащил некоторые из моих собственных проектов с PHP 7.4 на PHP 8: мне потребовалось около часа на каждый проект. Так что, у нас осталось ещё меньше поводов откладывать миграцию.
Система типов
Наконец-то в PHP добавят перечисления.
Ниже — пример их использования:
Кроме того, появился RFC-запрос на добавление в язык нового типа never.
Использование never будет означать, что функция с таким типом возвращаемого значения не сможет вернуть результат и должна прервать выполнение программы — выбросить исключение, вызвать exit или сделать это каким-то другим способом.
Отмечу, что never принципиально отличается от void: функция с возвращаемым значением типа void способна вернуть результат, а значит, прерывать работу программы нет необходимости. Такое нововведение может показаться слегка необычным, но оно обязательно найдёт применение в статическом анализе кода.
И ещё пару слов о статическом анализе: PhpStorm добавил встроенную поддержку анализаторов Psalm и PhpStan. После этого количество пользователей этих двух продуктов должно увеличиться.
К сожалению, дженерики (generics) по-прежнему нативно не поддерживаются. Есть несколько серьёзных проблем. В первую очередь, не забывайте, что PHP — это всё ещё язык с динамической типизацией. Здесь Nikita уже писал о связанных с этим проблемах. На мой взгляд, самый простой выход — нативно реализовать поддержку лишь так называемых runtime-erased generics, добавив в язык новый синтаксис без применения каких-либо дополнительных проверок типа во время выполнения и полагаясь на статический анализ. Однако, для этого требуется больше, чем просто техническое решение: нужно изменить мышление участников PHP-сообщества в целом. Может быть, когда-нибудь это станет возможным. Когда-нибудь.
Асинхронный PHP
Буквально недавно мы узнали, что в PHP 8.1 появятся корутины, также известные как файберы.
Простой пример использования файберов:
Хотя одних только файберов недостаточно для того, чтобы язык стал по-настоящему асинхронным. Они могут лишь стать маленькой шестерёнкой в «большой асинхронной машине».
Однако, соответствующий RFC снова вызвал интерес у «автолюбителей асинхронности», чему мы можем только радоваться. Популярность асинхронных фреймворков, таких как Amphp и ReactPHP, растёт: недавно Laravel объявил о встроенной поддержке Swoole и RoadRunner.
Экосистема PHP
Я не могу не вспомнить о новом релизе Composer 2.0, который вышел в октябре 2020 года. В этой версии есть несколько улучшений UX, но, что важнее всего, она демонстрирует большой прирост производительности. В условиях чистой установки прирост достигает 300%. Разница очень заметна на боевых проектах. Не зря пакетный менеджер Composer де-факто стал стандартом для PHP-разработчиков.
Мне нравится время от времени оценивать состояние экосистемы PHP, просматривая количество пакетов, доступных для скачивания. В прошлом году я говорил о ±25 миллионах загрузок в день. Сегодня это число увеличилось более чем вдвое, и мы уже видим ±60 миллионов загрузок в день.
Наконец, взгляните на этот график, в котором показано, как менялось количество доступных пакетов / версий с течением времени. Его можно найти на сайте Packagist.com. Вы можете сами оценить, как растёт экосистема. И конца этому не видно.
Дальше — больше
Давайте подытожим, пройдясь по всему, что было добавлено в PHP за последние годы. Если вы не следите за его развитием, материалы из списка помогут восполнить этот пробел. Я думаю, он наглядно показывает рост сообщества и команды разработчиков за последние годы. Уверен, что дальше будет ещё лучше.
Наши серверы можно использовать для разработки на PHP.
Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!
Что нового в PHP 8.1
Версия PHP 8.1 находится в активной разработке и будет выпущена 25 ноября 2021 г. Следует иметь в виду, что эта дата может измениться, если основная команда разработчиков решит, например, добавить дополнительный бета-выпуск. Мы уже знаем о новых возможностях, повышении производительности, изменениях и упразднении сомнительной функциональности. Давайте рассмотрим эти новшества по порядку.
Новые возможности
Как и в каждом выпуске, в PHP 8.1 добавлено несколько новых полезных возможностей. Имейте в виду, что в течение года этот список будет пополняться.
Перечисления rfc
В PHP 8.1 будут добавлены перечисления (enum)! Если вы не уверены, зачем они нужны, можете прочитать о них здесь.
Добавление перечислений будет значительным улучшением PHP — я, например, с нетерпением жду их появления в PHP 8.1. Вот пример того, как они будут выглядеть:
И вот как они будут использоваться:
Более подробно о том, как можно использовать перечисления, вы можете узнать из уже упомянутой статьи.
Файберы rfc
Файберы (fiber), или «зеленые потоки», представляют собой низкоуровневый механизм управления параллелизмом. Возможно, вам не придется использовать их в своих приложениях напрямую, но они будут широко применяться такими фреймворками, как Amphp и ReactPHP.
Вот простой пример использования файберов:
Если вы хотите узнать больше о файберах и о том, что они могут и чего не могут делать, прочтите эту статью.
Повышение производительности pr
Дмитрий Стогов добавил в opcache ряд улучшений, назвав их кешем наследования (inheritance cache). Эта возможность позволяет кешировать связи между классами и очень похожа на предзагрузку связанных классов в PHP 7.4.
Дмитрий сообщает, что в результате производительность повышается на 5–8 %, — одна из приятных мелочей, ожидаемых от PHP 8.1.
Распаковка массивов со строковыми ключами rfc
Распаковка массивов была доступна еще в PHP 7.4, но работала только с числовыми ключами. Строковые ключи не поддерживались, так как не было единого мнения относительно объединения дубликатов в массивах. В данном RFC эта проблема четко решается путем следования семантике array_merge :
Новый тип never rfc
Тип never можно использовать для указания того, что функция будет останавливать поток выполнения программы. Это можно сделать вызовом исключения или функции exit либо подобных ей.
never отличается от void тем, что void позволяет программе продолжить выполнение. Этот тип может показаться необычным новшеством, но на деле он будет весьма полезен для статических анализаторов.
Новая функция array_is_list rfc
Возможно, вы имели дело с задачами, когда нужно было определить, представляют ли ключи массива числовую последовательность 0, 1, 2, 3. подобно тому, как функция json_encode определяет, следует ли кодировать массив как массив или как объект.
В PHP 8.1 добавлена встроенная функция для определения того, является ли массив списком с такой семантикой или нет:
Финальные константы классов rfc
Константы классов в PHP могут быть переопределены при наследовании:
Новая функция fsync rfc
Поскольку синхронизация c диском — это операция файловой системы, функция fsync будет работать только с обычными файловыми потоками. При попытке синхронизации нефайловых потоков будет выдаваться предупреждение.
Явная нотация восьмеричных целочисленных литералов rfc
Теперь для обозначения восьмеричных чисел можно использовать префиксы 0o и 0O. Ранее принятая нотация, согласно которой к числу следовало добавлять префикс 0, также по-прежнему будет работать.
Изменения, которые могут затронуть существующий код
Хотя PHP 8.1 является младшей версией, она упраздняет некоторую сомнительную функциональность, а также вносит изменения, которые технически могут испортить уже существующий код. Давайте поговорим об этих нововведениях.
Никита проанализировал 2000 самых популярных пакетов на Packagist и обнаружил только 23 случая, на которые повлияет это изменение. Можно сделать вывод, что влияние этого формально критического изменения будет незначительным, поэтому было решено добавить его в PHP 8.1. Следует отметить, что большая часть разработчиков от этого только выиграет, поскольку оно положительно повлияет на производительность кода.
Переход от ресурсов к объектам
Эти изменения являются частью долгосрочной стратегии преобразования всех ресурсов в выделенные объекты. Подробнее об этом можно прочитать здесь.
Функции Fileinfo и объекты finfo
Функции IMAP и объекты IMAPConnection
Запрещена передача null в не поддерживающие null аргументы внутренних функций rfc
В PHP 8.1 при вызовах такого рода будет выдаваться предупреждение об их упразднении (deprecation), а в PHP 9 эти предупреждения станут ошибками типизации.
Мелкие изменения
С каждым выпуском в язык вносится множество небольших изменений. Все они перечислены в руководстве UPGRADING на GitHub — обязательно ознакомьтесь с ним, если хотите знать о таких мелочах.
Вот сводка наиболее существенных изменений:
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH больше не работает.
MYSQLI_STORE_RESULT_COPY_DATA больше не работает.
PDO::ATTR_STRINGIFY_FETCHES теперь работает и с логическим типом данных (boolean).
При использовании эмулированных подготовленных операторов целые числа и числа с плавающей запятой в наборах результатов PDO MySQL и SQLite будут возвращаться с использованием собственных типов PHP вместо строк.
На этом пока все. Я собираюсь регулярно обновлять эту статью в течение года, поэтому оформите подписку, если хотите быть в курсе. Вы рады скорому выходу PHP 8.1? Поделитесь своими ожиданиями со мной в Twitter!
Всех желающих приглашаем на интенсив «Поговорим о тестировании» (День 2). На этом занятии мы:
— Поговорим про тестируемый код и о том как его писать;
— Освоим написание Unit-тестов с использованием PHPUnit;
— A-TRIP, TDD и Red-Green-Refactor;
— Посмотрим на идеологию CI/CD и запуск автоматического прогона наших тестов в Travis.
К концу занятия научимся писать правильные Unit-тесты. РЕГИСТРАЦИЯ

