- PVSM.RU - https://www.pvsm.ru -

PHP-Дайджест № 194 (1 – 14 декабря 2020)

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 1

Свежая подборка со ссылками на новости и материалы. В выпуске: Enum в PHP 8.1, удаление Serializable и ограничение $GLOBALS, а также другие новости из PHP Internals, PhpStorm 2020.3, Symfony UX, порция полезных инструментов, видео, и первый PHP Дайджест Стрим.

Приятного чтения!

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 2 Новости и релизы

  • habr PhpStorm 2020.3 [1]: PHP 8, атрибуты, PHPStan и Psalm, Xdebug 3, Tailwind CSS и совместная разработка.
  • JetBrains Qodana EAP [2] — Новый продукт от JetBrains для запуска PhpStorm в CI.
  • Slack куплен за $27 млрд [3] — Примечательно, то что бекенд Слэка изначально написан на PHP [4], а позже расширен на Hack [5].
  • WordPress 5.6 [6] — C бета-поддержкой PHP 8.
  • Статистика версий PHP – 2020.2 [7] — Традиционная подборка статистики на основе данных, которые Composer отправляет при подключении к packagist.org.
    PHP 7.4: 42.61% (+22.55)
    PHP 7.3: 27.05% (-3.00)
    PHP 7.2: 15.28% (-12.21)
    PHP 7.1: 7.45% (-4.1)
    PHP 5.6: 2.71% (-2.28)
    PHP 7.0: 2.70% (-1.30)

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 4 PHP Internals

  • [RFC] Deprecate passing null to non-nullable arguments of internal functions [8] — В текущих версиях PHP стандартные функции без ошибок принимают null в качестве аргумента даже, когда параметр не nullable. Например, str_contains("", null)

    Проблема в том, что если объявить пользовательскую функцию с такой сигнатурой, то там аргумент null вызовет ошибку.

    str_contains("", null);
    // > No errors
    
    function _str_contains ( string $haystack , string $needle ) : bool
    {
        return true;
    }
    
    _str_contains("", null);
    // > Fatal error: Uncaught TypeError: Argument 2 passed to _str_contains() must be of the type string, null given
    

    Предлагается поэтапно исправить это несоответствие и в 8.1 бросать deprecation notice.

    Ну а пока можно добавить declare(strict_types=1); и проблема решена.

  • [RFC] Restrict $GLOBALS usage [9] — Сейчас, чтобы $GLOBALS вел себя как массив, приходится поддерживать еще один специальный тип INDIRECT и предоставлять прямую ссылку на внутреннюю таблицу символов PHP. Поддержка этого влияет на производительность всех операций с массивами в PHP.

    В этом RFC Никита Попов предлагает ограничить использование $GLOBALS.

    Продолжат работать чтение, запись, isset и unset:

    $GLOBALS['x'] = 1;
    
    echo $GLOBALS['x']
    
    isset($GLOBALS['x']);
    unset($GLOBALS['x']);

    И он не будет содержать рекурсивную ссылку на самого себя.

    А вот попытка изменить саму переменную $GLOBALS вызовет ошибку:

    $GLOBALS = [];
    $GLOBALS =& $x;
    $x =& $GLOBALS;
    unset($GLOBALS);

    Также ошибка будет, если передать $GLOBALS по ссылке в функцию:

    asort($GLOBALS);
    // > Compile-time error

    Забавный факт: именно об этом говорил Дмитрий Стогов на стриме [10] отвечая на вопрос: «что стоило бы убрать в следующих версиях PHP».

  • [RFC] Phasing out Serializable [11] — В 7.4 был введен новый механизм сериализации [12]: наряду со старым интерфейсом Serialiazable были добавлены магические методы __serialize() и __unserialize().

    Предлагается постепенно полностью избавиться от Serializable. В PHP 8.1 его использование будет генерировать deprecation notice, а в PHP 9.0 — compile-time error.

  • [RFC] Enumerations [13] — Ilija Tovilo и Larry Garfield провели исследования enum во всех языках [14] и представили RFC, который вдохновлен Swift, Rust, и Kotlin.

    Enum это по сути класс, а его возможные значения — это объекты. Это означает, что, на вопрос «как бы вели себя Enums в ситуации X» можно ответить «так же, как и любой другой объект». Но есть несколько исключений.

    Описывается с помощью ключевых слов enum и case:

    enum Suit {
      case Hearts;
      case Diamonds;
      case Clubs;
      case Spades;
    }

    Переменным можно присваивать одно из значений:

    $val = Suit::Diamonds;
    
    function pick_a_card(Suit $suit) { ... }
    
    pick_a_card($val);        // OK
    pick_a_card(Suit::Clubs); // OK
    pick_a_card('Spades');    // TypeError

    Enum ведут себя как синглтон-объекты:

    $a = Suit::Spades;
    $b = Suit::Spades;
    
    $a === $b; // true
    
    $a instanceof Suit;         // true
    $a instanceof Suit::Spades; // true

    Есть возможность объявить скалярные Enum. Их можно прозрачно использовать в контексте, где ожидаются скалярные значения:

    enum Suit: string {
      case Hearts = 'H';
      case Diamonds = 'D';
      case Clubs = 'C';
      case Spades = 'S';
    }
    
    echo "I hope I draw a " . Suit::Spades;
    // prints "I hope I draw a S".

    Enum может иметь методы, в том числе статические. Пример использования метода для вывода списка опций чекбокса:

    enum UserStatus: string {
      case Pending = 'pending';
      case Active = 'active';
      case Suspended = 'suspended';
      case CanceledByUser = 'canceled';
    
      public function label(): string {
        return match($this) {
          UserStatus::Pending => 'Pending',
          UserStatus::Active => 'Active',
          UserStatus::Suspended => 'Suspended',
          UserStatus::CanceledByUser => 'Canceled by user',
        };
      }
    }
    
    foreach (UserStatus::cases() as $key => $val) {
      printf('<option value="%s">%s</option>n', $key, $val->label());
    }

    Из открытых пока еще вопросов остаются:

    • Могут ли иметь свои методы значения case?
    • Можно ли использовать конкретное значение в качестве тайпхинта? function stuff(Suit::Heart|Suit:Diamond $card) { ... }
    • Разрешена ли сериализация Enum?
    • < Должно ли слово enum быть полностью ключевым? Тогда сломается весь код, который использует имя класса Enum. Или стоит сделать контекстное ключевое слово вот так: enum class UserStatus {...}

  • [RFC] Algebraic Data Types [15] — Предложение про Enum является первым шагом большого плана по реализации алгебраического типа в PHP. В качестве *возможных* дальнейших шагов рассматриваются tagged unions [16] и pattern matching [17].
  • [RFC] Direct execution opcode file without php source code file [18] — Предлагается сделать возможным сохранять бинарный файл опкеша и запускать его уже без исходника. По сути, что-то очень похожее на питоновские файлы .pyc / .pyo.

    Формат опкода в PHP нестабилен и несовместим от версии к версии. Чтобы решить эту проблему, предлагается скомпилированный таким образом файл помечать в начале меткой <?phpo%php_version_id%.

    Такой файл можно будет подключать через стандартные функции include(), include_once(), require(), require_once().

  • [RFC] Wall-Clock Time Based Execution Timeout [19] — PHP измеряет всякого рода таймауты используя процессорное время. Это значит время затраченной в sleep() или сетевых запросах не учитывается. Например, это влияет на использование ini-настройки max_execution_time.

    В данном RFC всего лишь предлагается ввести новую установку max_execution_wall_time, которая бы учитывала реальное время вместо процессорного.

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 5 Инструменты

  • itsgoingd/clockwork v5.0 [20] — Отладочная панель и расширение для Chrome, которое добавляет вкладку в dev tools для отладки PHP-приложений. Подробный разбор инструмента смотрите в video Пятиминутке PHP [21].
  • nicofff/LazyIter [22] — Библиотека для работы с массивами в виде цепочек вызовов. Вдохновленная итератором из Rust. Пост про строгую типизацию [23] в поддержку.
  • veewee/composer-run-parallel [24] — Позволяет параллельно запускать команды из секции «scripts» в composer.json.
  • clue/phar-composer [25] — Берет проект с composer.json и создает исполняемый архив phar со всеми зависимостями.
  • clue/commander [26] — Для быстрого создания консольных команд.
  • quasilyte/phpgrep 1.0 [27] — Инструмент для поиска по PHP-коду – как grep, только с «пониманием» синтаксиса PHP.

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 7 Symfony

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 9 Laravel

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 14 Yii

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 16 Async PHP

  • clue/reactphp-zenity [46] — Обертка над Zenity для создания GUI приложений на PHP. Работает из коробки на Ubuntu.

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 17 Материалы для обучения

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 24 Аудио/Видео

PHP-Дайджест № 194 (1 – 14 декабря 2020) - 30 Занимательное

Сегодня первый раз проведу стрим по PHP дайджесту. Все новости и ссылки из выпуска + больше деталей, обзор присланного, интересное но не вошедшее в выпуск, и конкурс со слониками.
Начало в 20:00 Москва, Минск / 19:00 Киев.


Если вы заметили ошибку или неточность — сообщите, пожалуйста, в личку хабра [70] или телеграм [71].

Больше новостей и комментариев в Telegram-канале PHP Digest [72].

Прислать ссылку [73]
Поиск ссылок по всем дайджестам [74]
Предыдущий выпуск: PHP-Дайджест № 193 [75]

Автор: Роман Пронский

Источник [76]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/news/359739

Ссылки в тексте:

[1] PhpStorm 2020.3: https://habr.com/ru/company/JetBrains/blog/531828/

[2] JetBrains Qodana EAP: https://blog.jetbrains.com/phpstorm/2020/12/early-access-program-for-qodana-a-new-static-analysis-and-quality-management-tool-by-jetbrains-is-open/

[3] Slack куплен за $27 млрд: https://techcrunch.com/2020/12/01/salesforce-buys-slack/

[4] написан на PHP: https://slack.engineering/taking-php-seriously/

[5] на Hack: https://slack.engineering/hacklang-at-slack-a-better-php/

[6] WordPress 5.6: https://wordpress.org/news/2020/12/simone/

[7] Статистика версий PHP – 2020.2: https://blog.packagist.com/php-versions-stats-2020-2-edition/

[8] [RFC] Deprecate passing null to non-nullable arguments of internal functions: https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg

[9] [RFC] Restrict $GLOBALS usage: https://wiki.php.net/rfc/restrict_globals_usage

[10] говорил Дмитрий Стогов на стриме: https://www.youtube.com/watch?v=QSszmWIrRyw&t=6289

[11] [RFC] Phasing out Serializable: https://wiki.php.net/rfc/phase_out_serializable

[12] новый механизм сериализации: https://wiki.php.net/rfc/custom_object_serialization

[13] [RFC] Enumerations: https://wiki.php.net/rfc/enumerations

[14] исследования enum во всех языках: https://github.com/Crell/enum-comparison

[15] [RFC] Algebraic Data Types: https://wiki.php.net/rfc/adts

[16] tagged unions: https://wiki.php.net/rfc/tagged_unions

[17] pattern matching: https://wiki.php.net/rfc/pattern-matching

[18] [RFC] Direct execution opcode file without php source code file: https://wiki.php.net/rfc/direct-execution-opcode

[19] [RFC] Wall-Clock Time Based Execution Timeout: https://wiki.php.net/rfc/max_execution_wall_time

[20] itsgoingd/clockwork v5.0: https://github.com/itsgoingd/clockwork

[21] Пятиминутке PHP: https://www.youtube.com/watch?v=I-gUoz-Meio

[22] nicofff/LazyIter: https://github.com/nicofff/LazyIter

[23] Пост про строгую типизацию: https://nicolasfar.medium.com/on-strong-type-checking-in-php-and-the-opportunities-it-presents-today-4eb0f7ffea8c

[24] veewee/composer-run-parallel: https://github.com/veewee/composer-run-parallel

[25] clue/phar-composer: https://github.com/clue/phar-composer

[26] clue/commander: https://github.com/clue/commander

[27] quasilyte/phpgrep 1.0: https://github.com/quasilyte/phpgrep

[28] Symfony UX: https://symfony.com/blog/new-in-symfony-the-ux-initiative-a-new-javascript-ecosystem-for-symfony?utm_medium=feed

[29] Stimulus js: https://stimulusjs.org/

[30] symfony/ux: https://github.com/symfony/ux

[31] Неделя Symfony #728 (7-13 декабря 2020): https://symfony.com/blog/a-week-of-symfony-728-7-13-december-2020?utm_medium=feed

[32] Делаем Action-Domain-Responder на Symfony: https://medium.com/swlh/implementing-action-domain-responder-pattern-with-symfony-606539eea3a7

[33] Symfony и гексагональная архитектура: https://minompi.medium.com/symfony-and-hexagonal-architecture-b3c4704e94de

[34] Symfony Workshop 2020: https://www.youtube.com/watch?v=oFddUtFNkCs&list=PLQH1-k79HB39w7dmGtLj4JGJ7HoucbcMx&index=4

[35] Представлен Laravel Sail: https://github.com/laravel/sail

[36] tailflow/laravel-orion 1.0: https://github.com/tailflow/laravel-orion

[37] asantibanez/laravel-eloquent-state-machines: https://github.com/asantibanez/laravel-eloquent-state-machines

[38] lukeraymonddowning/honey: https://github.com/lukeraymonddowning/honey

[39] Как обновить October CMS до Laravel 6?: https://habr.com/ru/post/531936/

[40] Стрим Laravel Internals #2: https://www.youtube.com/watch?v=ixI2R3W76N8

[41] Laravel at Scale: Framework, Community & Ecosystem: https://www.youtube.com/watch?v=MZ0ZeWNJyhY

[42] Laravel–Дайджест (6–13 декабря 2020): https://habr.com/ru/post/532754/

[43] Yii 1.1.23: https://www.yiiframework.com/news/318/yii-1-1-23-is-released

[44] yiisoft/cookies: https://github.com/yiisoft/cookies

[45] SOLID на практике. Принцип открытости-закрытости и ActiveQuery Yii2: https://habr.com/ru/post/531186/

[46] clue/reactphp-zenity: https://github.com/clue/reactphp-zenity

[47] Профилирование PHP-приложений на продакшне: https://calendar.perfplanet.com/2020/profiling-php-in-production-at-scale/

[48] wikimedia/php-excimer: https://github.com/wikimedia/php-excimer/

[49] wikimedia/arc-lamp: https://github.com/wikimedia/arc-lamp/

[50] AWS Lambda теперь может запускать PHP, используя контейнеры Docker: https://mnapoli.fr/aws-lambda-php-docker-containers/

[51] Переносим билды с Travis CI на GitHub Actions: https://freek.dev/1853-moving-php-and-laravel-tests-from-travis-ci-to-github-actions

[52] php.watch: Детально о JIT в PHP 8: https://php.watch/articles/jit-in-depth

[53] Как должен выглядеть Faker 2.0: https://github.com/Nyholm/next-faker

[54] прекратил работу над ней: https://habr.com/ru/post/526098/#:~:text=%D0%97%D0%B0%D0%BA%D0%B0%D1%82%20PHP%20Faker

[55] форк: https://github.com/fakerphp/Faker

[56] Руководство по разработке расширений для PHP от Zend: https://www.zend.com/sites/zend/files/pdfs/whitepaper-zend-php-extensions.pdf

[57] НЕкостыль: gRPC-клиент на PHP в продакшене: https://habr.com/ru/company/skyeng/blog/531676/

[58] Сравним C++, JS, Python, Python + numba, PHP7, PHP8, и Golang на примере расчёта “Простое Число”: https://habr.com/ru/post/532432/

[59] Простой Telegram бот, который задаёт 1 вопрос: https://habr.com/ru/post/531790/

[60] Улучшаем архитектуру: Инверсия и внедрение зависимостей, наследование и композиция: https://habr.com/ru/post/531250/

[61] Масштабирование MySQL в Slack с помощью Vitess: https://yupe.ru/post/masshtabirovanie-mysql-v-slack-s-pomoshchyu-vitess.html

[62] Книга «PHP для веба» от Matthias Noback: https://leanpub.com/php-for-web-ru

[63] lex111: https://habr.com/ru/users/lex111/

[64] Видеокурс по PHP на 6.5 часов для абсолютных новичков: https://www.youtube.com/watch?v=2eebptXfEvw

[65] Intro to PHP | Learn PHP The Right Way: https://www.youtube.com/watch?v=sVbEyFZKgqk&list=PLr3d3QYzkw2xabQRUpcZ_IBk9W50M9pe-

[66] Видеокурс ООП в PHP для новичков: https://www.youtube.com/watch?v=ncibYs9zAx8&list=PLQH1-k79HB3_LMrc9ytoOirBLaRlkM5Bi

[67] Пишем Блог на PHP: https://www.youtube.com/watch?v=TkZkCmKlvq0&list=PLIUUp_4cT9KZ2BaKOOxaOQFSVc9dsr8dM

[68] Что нового в PHP 8.0: https://www.youtube.com/watch?v=uU1-ZqIbYes

[69] слоник в честь 15-летия Symfony: https://shop.symfony.com/products/collector-15y-o-small-symfony-elephpant-grey-color

[70] личку хабра: https://habrahabr.ru/conversations/pronskiy/

[71] телеграм: https://t.me/pronskiy

[72] PHP Digest: https://t.me/phpdigest

[73] Прислать ссылку: https://bit.ly/php-digest-add-link

[74] Поиск ссылок по всем дайджестам: https://pronskiy.com/php-digest/

[75] Предыдущий выпуск: PHP-Дайджест № 193: https://habr.com/ru/post/530562/

[76] Источник: https://habr.com/ru/post/532950/?utm_source=habrahabr&utm_medium=rss&utm_campaign=532950