HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p><strong>Вместе с PHP-разработчиками<a>Александром Макаровым</a>, Валентином Удальцовым и наставником Хекслета по PHP Владленом Гилязетдиновым разбираемся, какие новые фичи появились в PHP 8.2, насколько эти изменения глобальны и какую роль в них сыграл проект РHP Foundation.</strong></p>
1 <p><strong>Вместе с PHP-разработчиками<a>Александром Макаровым</a>, Валентином Удальцовым и наставником Хекслета по PHP Владленом Гилязетдиновым разбираемся, какие новые фичи появились в PHP 8.2, насколько эти изменения глобальны и какую роль в них сыграл проект РHP Foundation.</strong></p>
2 <blockquote><p>Эта статья - саммари стрима YouTube-канала PHP Point</p>
2 <blockquote><p>Эта статья - саммари стрима YouTube-канала PHP Point</p>
3 </blockquote><h2>Содержание</h2>
3 </blockquote><h2>Содержание</h2>
4 <ul><li><a>Главные изменения в PHP 8.2</a></li>
4 <ul><li><a>Главные изменения в PHP 8.2</a></li>
5 <li><a>Какие еще изменения произошли</a></li>
5 <li><a>Какие еще изменения произошли</a></li>
6 <li><a>Какие изменения PHP 8.2 еще в разработке</a></li>
6 <li><a>Какие изменения PHP 8.2 еще в разработке</a></li>
7 </ul><h2>Главные изменения в PHP 8.2</h2>
7 </ul><h2>Главные изменения в PHP 8.2</h2>
8 <h3>Readonly-классы</h3>
8 <h3>Readonly-классы</h3>
9 <p>Поля readonly сделали еще до версии 8.2. Раньше писать в них код и читать его можно было только в конструкторе. А теперь для этого не нужно помечать каждое поле - достаточно<a>отметить весь класс</a>как readonly.</p>
9 <p>Поля readonly сделали еще до версии 8.2. Раньше писать в них код и читать его можно было только в конструкторе. А теперь для этого не нужно помечать каждое поле - достаточно<a>отметить весь класс</a>как readonly.</p>
10 <p>Как выглядел код в предыдущих версиях PHP:</p>
10 <p>Как выглядел код в предыдущих версиях PHP:</p>
11 <p>Как выглядит код в PHP 8.2:</p>
11 <p>Как выглядит код в PHP 8.2:</p>
12 <p>Но у фичи есть особенности:</p>
12 <p>Но у фичи есть особенности:</p>
13 <ol><li>Readonly-классы недоступны для классов с необъявленными типами</li>
13 <ol><li>Readonly-классы недоступны для классов с необъявленными типами</li>
14 <li>Также readonly-классы недоступны для классов со статическими свойствами</li>
14 <li>Также readonly-классы недоступны для классов со статическими свойствами</li>
15 <li>Если мы захотим наследоваться от старого readonly-класса, новый тоже должен быть Readonly</li>
15 <li>Если мы захотим наследоваться от старого readonly-класса, новый тоже должен быть Readonly</li>
16 </ol><blockquote><h3>Изучите классы PHP на Хекслете</h3>
16 </ol><blockquote><h3>Изучите классы PHP на Хекслете</h3>
17 <p>Пройдите наш<a>курс "PHP: Погружаясь в классы"</a>, чтобы узнать о позднем связывании, трейтах и абстрактных классах, а также понять, как устроено ООП внутри PHP.</p>
17 <p>Пройдите наш<a>курс "PHP: Погружаясь в классы"</a>, чтобы узнать о позднем связывании, трейтах и абстрактных классах, а также понять, как устроено ООП внутри PHP.</p>
18 </blockquote><h3>Типы в виде дизъюнктивной нормальной формы (ДНФ)</h3>
18 </blockquote><h3>Типы в виде дизъюнктивной нормальной формы (ДНФ)</h3>
19 <p>Теперь вместо того, чтобы указывать тип mixed для аргументов в методах, можно просто<a>перечислять необходимые типы</a>через амперсанд.</p>
19 <p>Теперь вместо того, чтобы указывать тип mixed для аргументов в методах, можно просто<a>перечислять необходимые типы</a>через амперсанд.</p>
20 <p>Как выглядел код в предыдущих версиях PHP:</p>
20 <p>Как выглядел код в предыдущих версиях PHP:</p>
21 <p>Как выглядит код в PHP 8.2:</p>
21 <p>Как выглядит код в PHP 8.2:</p>
22 <p>Пожелание от меня: будьте осторожны с этой фичей. Она позволяет много методов объединять в один. Если бы я программировал приложения, то так не делал бы. А вот во фреймворках она будет очень кстати, потому что иногда, ради красивой API, мы сознательно жертвуем такой вот правильностью - используем подход с mixed-типами в сигнатуре.</p>
22 <p>Пожелание от меня: будьте осторожны с этой фичей. Она позволяет много методов объединять в один. Если бы я программировал приложения, то так не делал бы. А вот во фреймворках она будет очень кстати, потому что иногда, ради красивой API, мы сознательно жертвуем такой вот правильностью - используем подход с mixed-типами в сигнатуре.</p>
23 <h3>Самостоятельные типы null, false и true</h3>
23 <h3>Самостоятельные типы null, false и true</h3>
24 <p>Это изменение единогласно приняла вся команда разработчиков PHP, так как в ядре PHP есть методы, классы и функции, которые возвращают false или true.</p>
24 <p>Это изменение единогласно приняла вся команда разработчиков PHP, так как в ядре PHP есть методы, классы и функции, которые возвращают false или true.</p>
25 <p>Если у вас метод никогда не возвращает false, то теперь<a>можно указать</a>, что он возвращает true или значение. Или наоборот, null и значение, или false и значение. Фича удобная и делает язык немного строже.</p>
25 <p>Если у вас метод никогда не возвращает false, то теперь<a>можно указать</a>, что он возвращает true или значение. Или наоборот, null и значение, или false и значение. Фича удобная и делает язык немного строже.</p>
26 <p>Как выглядел код в предыдущих версиях PHP:</p>
26 <p>Как выглядел код в предыдущих версиях PHP:</p>
27 <p>Как выглядит код в PHP 8.2:</p>
27 <p>Как выглядит код в PHP 8.2:</p>
28 <h3>Модуль "Random"</h3>
28 <h3>Модуль "Random"</h3>
29 <p><a>Random</a>- это целый пак разных интерфейсов. Особенности фичи:</p>
29 <p><a>Random</a>- это целый пак разных интерфейсов. Особенности фичи:</p>
30 <ol><li>Разработчики сделали объектно-ориентированный API</li>
30 <ol><li>Разработчики сделали объектно-ориентированный API</li>
31 <li>Каждый инстанс независимый - то есть для разных целей можно инстанцировать n-штук псевдослучайных генераторов, которые никогда не пересекутся. Стало более безопасно.</li>
31 <li>Каждый инстанс независимый - то есть для разных целей можно инстанцировать n-штук псевдослучайных генераторов, которые никогда не пересекутся. Стало более безопасно.</li>
32 <li>Mersenne twister заменен на интерфейс Engine. Раньше mt_rand() надо было инициализировать. Он был нужен не для всяких крипто-фич, а для того чтобы, например, сортировать массивы в случайном порядке. mt_rand() работал достаточно быстро, поэтому использовать его для утилитарных задач было неплохо. Теперь его заменили на интерфейс Engine, который предоставляет готовые реализации.</li>
32 <li>Mersenne twister заменен на интерфейс Engine. Раньше mt_rand() надо было инициализировать. Он был нужен не для всяких крипто-фич, а для того чтобы, например, сортировать массивы в случайном порядке. mt_rand() работал достаточно быстро, поэтому использовать его для утилитарных задач было неплохо. Теперь его заменили на интерфейс Engine, который предоставляет готовые реализации.</li>
33 </ol><p>Как выглядит код в PHP 8.2:</p>
33 </ol><p>Как выглядит код в PHP 8.2:</p>
34 <h3>Константы в трейтах</h3>
34 <h3>Константы в трейтах</h3>
35 <p>Теперь можно<a>объявлять константы внутри трейтов</a>. Особенность фичи - нельзя получить доступ к константе через имя трейта, но можно через класс, который использует этот трейт.</p>
35 <p>Теперь можно<a>объявлять константы внутри трейтов</a>. Особенность фичи - нельзя получить доступ к константе через имя трейта, но можно через класс, который использует этот трейт.</p>
36 <p>Очень логичное изменение, на мой взгляд. Трейт сам по себе - это копипаст. Копипаст - штука опасная, но иногда полезная (у нас есть принцип "don't repeat yourself"). И трейт - это один самых неинвазивных способов что-то повторить, который легко потом отрефакторить.</p>
36 <p>Очень логичное изменение, на мой взгляд. Трейт сам по себе - это копипаст. Копипаст - штука опасная, но иногда полезная (у нас есть принцип "don't repeat yourself"). И трейт - это один самых неинвазивных способов что-то повторить, который легко потом отрефакторить.</p>
37 <p>Как выглядит код в PHP 8.2:</p>
37 <p>Как выглядит код в PHP 8.2:</p>
38 <h3>Динамические свойства объявлены устаревшими</h3>
38 <h3>Динамические свойства объявлены устаревшими</h3>
39 <p>В классах PHP можно было динамически присваивать значения свойствам, которые мы не объявили ранее, и эти свойства появлялись после классов.</p>
39 <p>В классах PHP можно было динамически присваивать значения свойствам, которые мы не объявили ранее, и эти свойства появлялись после классов.</p>
40 <p>Теперь<a>так сделать нельзя</a>- будет появляться Deprecation notice. Но если сильно нужно, динамическими свойствами можно пользоваться, если пометить класс аннотацией #[\AllowDynamicProperties]. В экземплярах stdClass динамические свойства по-прежнему можно использовать.</p>
40 <p>Теперь<a>так сделать нельзя</a>- будет появляться Deprecation notice. Но если сильно нужно, динамическими свойствами можно пользоваться, если пометить класс аннотацией #[\AllowDynamicProperties]. В экземплярах stdClass динамические свойства по-прежнему можно использовать.</p>
41 <p>Как выглядел код в предыдущих версиях PHP:</p>
41 <p>Как выглядел код в предыдущих версиях PHP:</p>
42 <p>Как выглядит код в PHP 8.2:</p>
42 <p>Как выглядит код в PHP 8.2:</p>
43 <h3>#[\SensitiveParameter]</h3>
43 <h3>#[\SensitiveParameter]</h3>
44 <p>Это маленькая, но очень классная фича, которая мельком упоминается в официальном анонсе.</p>
44 <p>Это маленькая, но очень классная фича, которая мельком упоминается в официальном анонсе.</p>
45 <p>Параметры в методах теперь<a>можно обозначить</a>как #[\SensitiveParameter]. Ниже в коде так отмечен параметр $secret, и в логах вместо значения параметра secret написано (Object(SensitiveParameterValue).</p>
45 <p>Параметры в методах теперь<a>можно обозначить</a>как #[\SensitiveParameter]. Ниже в коде так отмечен параметр $secret, и в логах вместо значения параметра secret написано (Object(SensitiveParameterValue).</p>
46 <p>Считаю это изменение очень крутым, так как теперь у нас не будут утекать всякие ключи от API, пароли от базы. Команда разработчиков PHP практически единогласно проголосовала за эту фичу.</p>
46 <p>Считаю это изменение очень крутым, так как теперь у нас не будут утекать всякие ключи от API, пароли от базы. Команда разработчиков PHP практически единогласно проголосовала за эту фичу.</p>
47 <blockquote><h3>Читайте также:</h3>
47 <blockquote><h3>Читайте также:</h3>
48 <p>Язык программирования PHP:<a>рейтинг, сферы применения, прогнозы экспертов</a></p>
48 <p>Язык программирования PHP:<a>рейтинг, сферы применения, прогнозы экспертов</a></p>
49 </blockquote><h2>Какие еще изменения произошли</h2>
49 </blockquote><h2>Какие еще изменения произошли</h2>
50 <h3>Расширение enum в константах</h3>
50 <h3>Расширение enum в константах</h3>
51 <p>Раньше, чтобы использовать enum, надо было дублировать их значение. Это было очень неприятно: enum есть, а в объявлениях констант нельзя было из них что-то использовать. Теперь можно: новая фича уравнивает весь синтаксис. Классно, что язык эволюционирует в сторону удобства и большей консистентности.</p>
51 <p>Раньше, чтобы использовать enum, надо было дублировать их значение. Это было очень неприятно: enum есть, а в объявлениях констант нельзя было из них что-то использовать. Теперь можно: новая фича уравнивает весь синтаксис. Классно, что язык эволюционирует в сторону удобства и большей консистентности.</p>
52 <h3>iterator_*() + iterables</h3>
52 <h3>iterator_*() + iterables</h3>
53 <p>Теперь<a>можно передавать</a>в методы iterator_*() тип \Traversables. Это просто замечательно, потому что раньше приходилось проверять, является ли аргумент объектом типа \Traversable, и если да, то надо было его конвертить. В PHP 8.2 можно больше не проводить эти проверки, что уменьшает количество кода и делает его более приятным и читаемым.</p>
53 <p>Теперь<a>можно передавать</a>в методы iterator_*() тип \Traversables. Это просто замечательно, потому что раньше приходилось проверять, является ли аргумент объектом типа \Traversable, и если да, то надо было его конвертить. В PHP 8.2 можно больше не проводить эти проверки, что уменьшает количество кода и делает его более приятным и читаемым.</p>
54 <h3>Расширена рефлексия</h3>
54 <h3>Расширена рефлексия</h3>
55 <ul><li>Можно узнать,<a>анонимный ли метод</a>- ReflectionFunction::isAnonymous()</li>
55 <ul><li>Можно узнать,<a>анонимный ли метод</a>- ReflectionFunction::isAnonymous()</li>
56 <li>Можно узнать,<a>есть ли у метода прототип</a>- ReflectionMethod::hasPrototype()</li>
56 <li>Можно узнать,<a>есть ли у метода прототип</a>- ReflectionMethod::hasPrototype()</li>
57 </ul><h3>Новые функции memory_reset_peak_usage</h3>
57 </ul><h3>Новые функции memory_reset_peak_usage</h3>
58 <p>Функции<a>сбрасывают статистику</a>по пиковому использованию памяти. Это очень полезно для EventLoop на PHP, Roadrunner и Swoole - мы сможем скинуть потребляемую память после запроса и измерить ту, которая ушла конкретно на один запрос.</p>
58 <p>Функции<a>сбрасывают статистику</a>по пиковому использованию памяти. Это очень полезно для EventLoop на PHP, Roadrunner и Swoole - мы сможем скинуть потребляемую память после запроса и измерить ту, которая ушла конкретно на один запрос.</p>
59 <h3>Что признали устаревшим или убрали</h3>
59 <h3>Что признали устаревшим или убрали</h3>
60 <ul><li>Интерполяция в строках вида ${}</li>
60 <ul><li>Интерполяция в строках вида ${}</li>
61 <li>Не рекомендуется использовать функции utf8_encode и utf8_decode</li>
61 <li>Не рекомендуется использовать функции utf8_encode и utf8_decode</li>
62 <li>Функции strtolower и strtoupper теперь не учитывают локаль - это круто, потому что версии PHP, установленные в двух системах Linux, могут работать по-разному из-за выбранной дефолтной локали.</li>
62 <li>Функции strtolower и strtoupper теперь не учитывают локаль - это круто, потому что версии PHP, установленные в двух системах Linux, могут работать по-разному из-за выбранной дефолтной локали.</li>
63 <li>Убрали много форматов callable:<ul><li>“self::method”</li>
63 <li>Убрали много форматов callable:<ul><li>“self::method”</li>
64 <li>“parent::method”</li>
64 <li>“parent::method”</li>
65 <li>“static::method”</li>
65 <li>“static::method”</li>
66 <li>[“self”, “method”]</li>
66 <li>[“self”, “method”]</li>
67 <li>[“parent”, “method”]</li>
67 <li>[“parent”, “method”]</li>
68 <li>[“static”, “method”]</li>
68 <li>[“static”, “method”]</li>
69 <li>[“Foo”, “Bar::Method”]</li>
69 <li>[“Foo”, “Bar::Method”]</li>
70 <li>[new Foo, “Bar::Method”]</li>
70 <li>[new Foo, “Bar::Method”]</li>
71 </ul></li>
71 </ul></li>
72 </ul><p>Мое мнение - на PHP 8.2 определенно стоит переходить хотя бы из-за крутых улучшений синтаксиса. Он все еще делает код более читаемым и понятным. Также разработчики пофиксили разные мелкие баги, которые мы не упомянули, но их было много.</p>
72 </ul><p>Мое мнение - на PHP 8.2 определенно стоит переходить хотя бы из-за крутых улучшений синтаксиса. Он все еще делает код более читаемым и понятным. Также разработчики пофиксили разные мелкие баги, которые мы не упомянули, но их было много.</p>
73 <blockquote><h3>Читайте также:</h3>
73 <blockquote><h3>Читайте также:</h3>
74 <p>Почему PHP<a>идеально подходит</a>для веб-разработки</p>
74 <p>Почему PHP<a>идеально подходит</a>для веб-разработки</p>
75 </blockquote><h2>Какие изменения PHP 8.2 еще в разработке</h2>
75 </blockquote><h2>Какие изменения PHP 8.2 еще в разработке</h2>
76 <p>Некоторые разработчики считают, что в новую версию PHP добавили очень мало изменений. На самом деле, в РHP 8.2 было много саппортных вещей: код вычищали, из него что-то убирали. Каждое изменение, которое вводили разработчики, непросто описать в фичах. Да и вряд ли всем будет интересно, какие куски кода рефакторили. Так что по объему работы релиз 8.2 не отличается от предыдущих релизов. Просто в нем чуть меньше фич.</p>
76 <p>Некоторые разработчики считают, что в новую версию PHP добавили очень мало изменений. На самом деле, в РHP 8.2 было много саппортных вещей: код вычищали, из него что-то убирали. Каждое изменение, которое вводили разработчики, непросто описать в фичах. Да и вряд ли всем будет интересно, какие куски кода рефакторили. Так что по объему работы релиз 8.2 не отличается от предыдущих релизов. Просто в нем чуть меньше фич.</p>
77 <p>Большие усилия к разработке версии 8.2 приложили ребята из PHP Foundation - проекта, который финансирует разработчиков, готовых контрибьютить в PHP.</p>
77 <p>Большие усилия к разработке версии 8.2 приложили ребята из PHP Foundation - проекта, который финансирует разработчиков, готовых контрибьютить в PHP.</p>
78 <p>PHP Foundation создали много известных компаний, среди которых JetBrains, Automattic, Laravel. Проект запустили 22 ноября 2021 года, и за год коллектив из десяти администраторов-добровольцев и шести разработчиков внесли почти половину коммитов в ядро языка PHP и расширения.</p>
78 <p>PHP Foundation создали много известных компаний, среди которых JetBrains, Automattic, Laravel. Проект запустили 22 ноября 2021 года, и за год коллектив из десяти администраторов-добровольцев и шести разработчиков внесли почти половину коммитов в ядро языка PHP и расширения.</p>
79 <p>В новую версию языка PHP Foundation имплементировал readonly-классы, самостоятельные типы null, false и true, тип true, типы в виде дизъюнктивной нормальной формы и получение свойств перечислений в константных выражениях. Также он объявил интерполяцию в строках вида ${} устаревшей.</p>
79 <p>В новую версию языка PHP Foundation имплементировал readonly-классы, самостоятельные типы null, false и true, тип true, типы в виде дизъюнктивной нормальной формы и получение свойств перечислений в константных выражениях. Также он объявил интерполяцию в строках вида ${} устаревшей.</p>
80 <p>Документация по PHP 8.2 еще в разработке, и разработчик PHP Foundation Джордж П. Баньярд сейчас отслеживает прогресс в изменениях. Вместе с командой он обсуждает эти нововведения:</p>
80 <p>Документация по PHP 8.2 еще в разработке, и разработчик PHP Foundation Джордж П. Баньярд сейчас отслеживает прогресс в изменениях. Вместе с командой он обсуждает эти нововведения:</p>
81 <ul><li><a>Автоматическая имплементация для enum Stringable</a></li>
81 <ul><li><a>Автоматическая имплементация для enum Stringable</a></li>
82 <li><a>Ассиметричная видимость</a></li>
82 <li><a>Ассиметричная видимость</a></li>
83 <li><a>Получение констант из класса</a></li>
83 <li><a>Получение констант из класса</a></li>
84 <li><a>Более понятные ошибки Date/Time</a></li>
84 <li><a>Более понятные ошибки Date/Time</a></li>
85 <li><a>Доработки по Readonly</a></li>
85 <li><a>Доработки по Readonly</a></li>
86 <li><a>Работа с инициализаторами произвольных статических переменных</a>.</li>
86 <li><a>Работа с инициализаторами произвольных статических переменных</a>.</li>
87 </ul><p>Помочь<a>составить документацию</a>может каждый из нас - это, как говорится, good first issue (несложные задачи, выполнить которые под силу новичкам).</p>
87 </ul><p>Помочь<a>составить документацию</a>может каждый из нас - это, как говорится, good first issue (несложные задачи, выполнить которые под силу новичкам).</p>
88 <p>Также PHP Foundation планирует выдвинуть на обсуждение новые изменения в<a>будущем релизе PHP 8.3</a>.</p>
88 <p>Также PHP Foundation планирует выдвинуть на обсуждение новые изменения в<a>будущем релизе PHP 8.3</a>.</p>
89 <blockquote><h3>Станьте профессиональным PHP-разработчиком с нуля за 10 месяцев</h3>
89 <blockquote><h3>Станьте профессиональным PHP-разработчиком с нуля за 10 месяцев</h3>
90 <p>На Хекслете есть<a>профессия "PHP-разработчик"</a>. Пройдите ее, чтобы изучить один из самых известных языков программирования, освоить популярные фреймворки и создать большое портфолио с проектами на GitHub.</p>
90 <p>На Хекслете есть<a>профессия "PHP-разработчик"</a>. Пройдите ее, чтобы изучить один из самых известных языков программирования, освоить популярные фреймворки и создать большое портфолио с проектами на GitHub.</p>
91 </blockquote>
91 </blockquote>