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>