Картинка: Gabriel Nunes.

Подборка свежих новостей и материалов из мира 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 сделано много улучшений по производительности. Судя по результатам свежих бенчмарков от одного из 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: videoPHP 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




Laravel




Yii




Статьи




Аудио/Видео




community Сообщество





Подписывайтесь на Telegram-канал PHP Digest.

Этот дайджест подготовлен совместно с Insolita. Если вам понравился выпуск, подпишитесь на Юлию в твиттере и поставьте плюс в пост, пожалуйста.


Заметили ошибку или опечатку? Сообщите в личку хабра или телеграм.

Прислать ссылку можно через форму или просто написав мне в телеграм.
Поиск ссылок по всем дайджестам
Предыдущий выпуск: PHP-Дайджест №214

Комментарии (11)


  1. joffer
    15.11.2021 15:50
    +9

    Ничего себе RFC по необъявленным свойствам! What a time to be alive!

    Пожалуй, хотел бы, чтобы это произошло, нас потихоньку подводят к всё большей осмысленности того, что ты пишешь => планировать то, что хочет метод, спланировать то, в каком порядке, какого типа, какого типа результат должно возвращать, а если таки запретят создание свойства "из воздуха", то нужно будет тщательнее думать, что должно быть в классе, не полагаясь на подход "добавим что надо по ходу пьесы".

    Либо же можно использовать класс-"помогайку" с флагом

    #[AllowDynamicProperties] и тогда новые свойства "из ниоткуда" будет получать один класс, что, в теории, облегчит контроль и понимание кода (правда, сам этот класс тогда будет тяготеть или к мусорке, или к "god object")


    1. bolk
      15.11.2021 16:28
      +13

      Лично я — за. В легаси-коде можно будет сделать

      class A extends \stdClass
      {
      }

      и ничего не поломается, простое исправление.


      1. pronskiy Автор
        15.11.2021 17:09
        +3

        Лучше все-таки с #[AllowDynamicProperties], потому что сработает даже если уже есть наследование.

        #[AllowDynamicProperties]
        class A extends B
        {
        }


        1. bolk
          15.11.2021 18:01
          +2

          Проблемы нет, экстендим B ))


        1. sergant210
          15.11.2021 21:13

          Или через интерфейс

          class A implements DymamicProperties


        1. leon0399
          16.11.2021 15:05
          +3

          Уж лучше тогда трейт `use DynamicProperties` внутри которого будет магия `__get/__set`. Таким образом и в Легаси динамические свойства останутся, и будут при этом использовать более оптимизированный подход, чем старая имплементация


    1. galliard
      15.11.2021 17:09
      +1

      В качестве помогайки вполне можно и ассоциативный массив использовать. Если без динамических полей упростится и ускорится код интерпретатора - то грех их не выпилить. Можно даже без атрибута #[AllowDynamicProperties]. А кому уж очень нужны именно динамические поля - __get/__set в помощь.


  1. 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

    Ждём фиксов?


  1. umbro2
    16.11.2021 12:59

    class FileStream { public resource $resource; } // Вызовет ошибку?

    Надеюсь, они не забудут сделать все возможные типы перед этим.


    1. pronskiy Автор
      16.11.2021 13:01
      +2

      Все ресурсы переделывают в объекты, поэтому тайпхинта resource не будет.
      Подробнее можно почитать вот тут https://php.watch/articles/resource-object


  1. Grikdotnet
    17.11.2021 02:52

    Никита потроллил php team -)))