Подборка свежих новостей и материалов из мира PHP.
В выпуске: последний релиз кандидат PHP 8.1 перед финальным релизом, бенчмарки PHP 8.1; в PHP 8.2 планируется задепрекейтить динамические свойства — добро или зло?; про перенос багов с bugs.php.net на GitHub; немного обновлен PSR-16.
Также в выпуске полезные статьи, видео и другие новости сообщества.
Приятного чтения!
Этот дайджест подготовлен совместно с Insolita. Если понравился выпуск, плюсаните пост, пожалуйста.
Новости
-
PHP 8.1.0 RC 6
Вышел последний релиз кандидат, а значит PHP 8.1 выйдет уже меньше, чем через две недели.- Интересный обзор новых фич PHP 8.1 сделал Mohamed Said (Core Laravel): Getting Ready for PHP 8.1
- Brent Roose: PHP 8.1 в 8 блоках кода
Кроме прочего, в PHP 8.1 сделано много улучшений по производительности. Судя по результатам свежих бенчмарков от одного из core PHP разработчиков, Symfony demo приложение работает на ~30% быстрее, чем на PHP 8.0.
Веб-приложения не на компонентах Symfony получат более скромный прирост, например для WordPress будет ~3-5%.
-
[RFC] Migrating to Github Issues
Предлагается перенести баги со старой системы bugs.php.net на GitHub в репозиторий php/php-src. Это касается всех багов, кроме секьюрити-проблем, которые не должны быть публичными.
В тестовом репозитории настроены шаблоны для баг-репортов запросов на фичи. Можно создать и посмотреть, как это будет выглядеть.
-
[RFC] Deprecate dynamic properties
На голосовании RFC с предложением задепрекейтить и впоследствии убрать динамические (необъявленные) свойства.class User { public $name; } $user = new User; // Assigns declared property User::$name. $user->name = 'foo'; // Oops, a typo: $user->nane = 'foo'; // PHP <= 8.1: Молча создает динамическое свойство $user->nane. // PHP 8.2: Вызывает предупреждение, но все равно создает динамическое свойство. // PHP 9.0: Выбрасывает исключение Error.
Это изменение не будет касаться классаstdClass
и унаследованных от него. А также не касается классов с магическими__get
/__set
.
Кроме того, в последней версии RFC добавлен еще атрибут#[AllowDynamicProperties]
. Его можно навесить на любой класс и в этом классе продолжат работать динамические свойства.
Предложение вызвало волну споров в твиттере. Вот пример треда с недовольными таким подходом. Это изменение обратной совместимости и потребуется обновлять много кода, да и вообще ломает динамическую сущность PHP — говорят они.
С другой стороны, отсутствие динамических свойств избавит от возможных ошибок и сделает код более прозрачным.
Но что еще важно, если в PHP 9.0 удастся убрать динамические свойства, то это существенно упростит код интерпретатора и уменьшит потребление памяти. Причем памяти для всех приложений.
Вот пример от Christoph M. Becker для иллюстрации проблемы с памятью свойств: 3v4l.org/f8OZj. И это не утечка памяти, а эффект создания хеш-таблицы свойств, нужной для поддержки динамических свойств.
Также в тему статья от одного из контрибьюторов Symfony о том, почему не стоит бояться депрекейшнов.
-
Обновлен PSR-16: Common Interface for Caching Libraries
Для пакета php-fig/simple-cache выпущены две новые версии. В 2.0.0 добавлены типы для аргументов, а в 3.0.0 — типы возвращаемых значений.
-
Локальная root-уязвимость в PHP-FPM
Уязвимость позволяет пользователю с низкими привилегиями (например, www-data) повысить свои привилегии до уровня root, используя ошибку в PHP-FPM. Хоть это серьезная проблема, но не RCE. То есть злоумышленнику сначала надо будет использовать другие техники, чтоб завладеть рабочим процессом PHP. По ссылке подробный разбор от исследователей.
Уязвимость исправлена в поддерживаемых ветках PHP 7.4.25 и PHP 8.0.12 и PHP 7.3.32.
На PHP 5.3—7.2 уязвимость тоже есть, но выпусков с исправлением не будет. Поэтому стоит срочно обновляться на поддерживаемые версии PHP.
Инструменты
-
PHPStan 1.0 — После шести лет разработки состоялся первый стабильный релиз статического анализатора. В релизе новый уровень проверки «9» и другие улучшения.
Есть свежее интервью с автором PHPStan: PHP Release Radar — Episode 13
- melbahja/seo — Библиотека с хелперами для организации карты сайта, мета-тегов, и других оптимизаций под поисковые системы. Без сторонних зависимостей
- PrinsFrank/php-geo-svg — Генерация географических svg-карт без использования сторонних сервисов.
- sapienphp/sapien — Предоставляет Request и Response вместо глобальных массивов $_GET, $_POST, $_COOKIE, и функций для работы с ответами. PHP 8.1+.
- Falseclock/AdvancedCMS — Библиотека для работы с CAdES — стандартом электронной подписи, представляющий собой расширенную версию стандарта электронной подписи CMS (Cryptographic Message Syntax). Прислал falseclock.
Symfony
- Что нового будет в Symfony 5.4
- Обновите Flex в ваших проектах на Symfony
- Создание кастомных правил PHPStan для проекта Symfony.
- An Asynchronous Request Bundle for Symfony
Laravel
- spatie/laravel-data — Позволяет создать многофункциональные переиспользуемые дата-объекты для Laravel. Пост в поддержку
- nunomaduro/larastan — Обёртка над статическим анализатором PHPStan, адаптированная под специфику Laravel.
- Deploying distributed web application — Laravel queued jobs
- How to update large data in Laravel
- Использование аттрибутов для роутинга
- Laravel Meetup #11: — Building APIs & Spotlight and Modals With Livewire.
- Паттерн Action-Domain-Responder
Yii
- Еще один пакет из Yii 3: yiisoft/yii-console
- Yii 3 будет не тем, чего я ожидал
Статьи
- Как ManyChat на PHP8 переезжал
- Перевод аудио-сообщений в текст в telegram при помощи Wit
- Сравнение php-fpm, nginx-unit и laravel-octane
- Эволюция PHP-объектов
- Современное шифрование в PHP с помощью библиотеки libsodium
- Паттерны проектирования на PHP: Visitor, Adapter vs. Bridge, Decorator vs. Proxy.
- Type variance in PHP — Никита Попов об особенностях системы типов в PHP.
- Интересный трюк от Larry Garfield с ридонли свойствами в PHP 8.1.
Аудио/Видео
- Свежий выпуск подкаста Пятиминутка PHP — Конференция YaTalks, первые впечатления от Yii3, PHP 8.1 уже близко, Tinkerwell, Mac mini на M1, механические клавиатуры и коврик для мыши с JSON API.
- Generics in PHP — Что такое дженерики и зачем они нужны от Brent Roose.
- Getting Started with PHP in 2022 — Интро в PHP от Mohamed Said (Core Laravel).
Сообщество
- PHP Is Killing Python — Конечно же, нет, но PHP хорош, а хейтить его — это как использовать любой другой стереотип.
- Tier-1 компании на рынке PHP в РФ
- Поход выходного дня, митапы в баре и 30 тысяч на блины: истории городских PHP-сообществ.
Подписывайтесь на Telegram-канал PHP Digest.
Этот дайджест подготовлен совместно с Insolita. Если вам понравился выпуск, подпишитесь на Юлию в твиттере и поставьте плюс в пост, пожалуйста.
Заметили ошибку или опечатку? Сообщите в личку хабра или телеграм.
Прислать ссылку можно через форму или просто написав мне в телеграм.
Поиск ссылок по всем дайджестам
← Предыдущий выпуск: PHP-Дайджест №214
Комментарии (11)
khazhinov
15.11.2021 17:44@pronskiy - После установки PHP8.1-RC6 на локальном окружении столкнулся с проблемой, не сталкивались ли Вы?
Вот детали по окружению:❯ php -v PHP 8.1.0RC6 (cli) (built: Nov 11 2021 19:52:08) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.0-dev, Copyright (c) Zend Technologies with Zend OPcache v8.1.0RC6, Copyright (c), by Zend Technologies ❯ uname -a Linux DESKTOP-I5PMM46 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux ❯ dpkg-query -l | grep -i php8.1 ii libapache2-mod-php8.1 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 amd64 server-side, HTML-embedded scripting language (Apache 2 module) ii php8.1 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 all server-side, HTML-embedded scripting language (metapackage) ii php8.1-cli 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 amd64 command-line interpreter for the PHP scripting language ii php8.1-common 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 amd64 documentation, examples and common module for PHP ii php8.1-opcache 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 amd64 Zend OpCache module for PHP ii php8.1-readline 8.1.0~rc6-1+ubuntu20.04.1+deb.sury.org+1 amd64 readline module for PHP
В результате Composer начал ломаться во всех местах. Даже вызов -v вызывает краш:
❯ composer -v Fatal error: Uncaught ErrorException: preg_match_all(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in phar:///usr/local/bin/composer/vendor/symfony/console/Formatter/OutputFormatter.php:137 Stack trace: #0 [internal function]: Composer\Util\ErrorHandler::handle(2, 'preg_match_all(...', 'phar:///usr/loc...', 137) #1 phar:///usr/local/bin/composer/vendor/symfony/console/Formatter/OutputFormatter.php(137): preg_match_all('#<(([a-z][a-z0-...', '', NULL, 256) #2 phar:///usr/local/bin/composer/vendor/symfony/console/Output/Output.php(155): Symfony\Component\Console\Formatter\OutputFormatter->format('') #3 phar:///usr/local/bin/composer/vendor/symfony/console/Output/Output.php(132): Symfony\Component\Console\Output\Output->write(Array, true, 16) #4 phar:///usr/local/bin/composer/vendor/symfony/console/Application.php(641): Symfony\Component\Console\Output\Output->writeln('', 16) #5 phar:///usr/local/bin/composer/vendor/symfony/console/Application.php(127): Symfony\Component\Console\Application->renderException(Object(ErrorException), Object(Symfony\Component\Console\Output\StreamOutput)) #6 phar:///usr/local/bin/composer/src/Composer/Console/Application.php(125): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #7 phar:///usr/local/bin/composer/bin/composer(67): Composer\Console\Application->run() #8 /usr/local/bin/composer(24): require('phar:///usr/loc...') #9 {main} thrown in phar:///usr/local/bin/composer/vendor/symfony/console/Formatter/OutputFormatter.php on line 137
При перестановке Composer под чистую валиться что-то вроде:
❯ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ❯ php composer-setup.php Warning: preg_match(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 461 All settings correct for using Composer Downloading... Warning: preg_replace(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 1252 Warning: preg_replace(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 1252 Warning: preg_replace(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 1252 Warning: preg_replace(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 1252 Warning: preg_replace(): Compilation failed: unrecognised compile-time option bit(s) at offset 0 in /home/khazhinov/composer-setup.php on line 1252 ...
Нашел вчерашний Issue - https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1830385.html
Ждём фиксов?
umbro2
16.11.2021 12:59class FileStream { public resource $resource; } // Вызовет ошибку?
Надеюсь, они не забудут сделать все возможные типы перед этим.
pronskiy Автор
16.11.2021 13:01+2Все ресурсы переделывают в объекты, поэтому тайпхинта resource не будет.
Подробнее можно почитать вот тут https://php.watch/articles/resource-object
joffer
Ничего себе RFC по необъявленным свойствам! What a time to be alive!
Пожалуй, хотел бы, чтобы это произошло, нас потихоньку подводят к всё большей осмысленности того, что ты пишешь => планировать то, что хочет метод, спланировать то, в каком порядке, какого типа, какого типа результат должно возвращать, а если таки запретят создание свойства "из воздуха", то нужно будет тщательнее думать, что должно быть в классе, не полагаясь на подход "добавим что надо по ходу пьесы".
Либо же можно использовать класс-"помогайку" с флагом
#[AllowDynamicProperties]
и тогда новые свойства "из ниоткуда" будет получать один класс, что, в теории, облегчит контроль и понимание кода (правда, сам этот класс тогда будет тяготеть или к мусорке, или к "god object")bolk
Лично я — за. В легаси-коде можно будет сделать
и ничего не поломается, простое исправление.
pronskiy Автор
Лучше все-таки с #[AllowDynamicProperties], потому что сработает даже если уже есть наследование.
bolk
Проблемы нет, экстендим B ))
sergant210
Или через интерфейс
leon0399
Уж лучше тогда трейт `use DynamicProperties` внутри которого будет магия `__get/__set`. Таким образом и в Легаси динамические свойства останутся, и будут при этом использовать более оптимизированный подход, чем старая имплементация
galliard
В качестве помогайки вполне можно и ассоциативный массив использовать. Если без динамических полей упростится и ускорится код интерпретатора - то грех их не выпилить. Можно даже без атрибута #[AllowDynamicProperties]. А кому уж очень нужны именно динамические поля -
__get
/__set
в помощь.