PHP Дайджест № 197 (11 – 25 января 2021)


    Свежая подборка со ссылками на новости и материалы. В выпуске: объекты в качестве ключей массивов и другие RFC предложения для PHP 8.1, запуск WebAssembly в PHP, о коллизиях в массивах, порция полезных инструментов, статьи, видео, PHP Дайджест Live.

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



    Новости и релизы



    PHP Internals


    • [RFC] Object keys in arrays
      Никита предлагает сделать возможным использование объектов в качестве ключей обычных массивов.

      $obj1 = new stdClass;
      $obj2 = new stdClass;
      
      $array = [];
      $array[$obj1] = 1;
      $array[$obj2] = 2;
      
      var_dump($array[$obj1]); // int(1)
      var_dump($array[$obj2]); // int(2)
      

      Сейчас для этого можно использовать SplObjectStorage или WeakMap, и они будут вести себя как массивы. Но все равно останутся ограничения. Например, их нельзя использовать в функциях array_* и многих других стандартных.

      Если предложение будет принято, то это также в будущем упростит добавление других видов ключей, например, целых чисел произвольной точности.

      Поводом для предложения послужил тот факт, что в RFC Enumerations предлагается сделать значения енамов объектами. И соответственно тогда их нельзя будет использовать в качестве ключей массивов. А это существенный минус.
    • [RFC] Object scoped RNG Implementations
      Функции для генерации псевдослучайных чисел rand() или mt_rand() будут генерировать одну и ту же последовательность для одинакового посевного (seed) значения srand(). Но из-за использования глобального состояния невозможно создать несколько генераторов с разными посевными значениями и использовать их одновременно.

      Автор предлагает добавить объектный API для работы с генераторами псевдослучайных последовательностей, чтоб решить проблему глобального состояния.
      $seed = 1234;
      $rng = new RNG\MT19937($seed);
      $array = [1, 2, 3, 4, 5];
      
      shuffle($array, $rng); // Результат всегда стабильный
      
      Если нужны криптографически стойкие случайные числа, то есть, которые устойчивы к атакам, то следует использовать: random_bytes() или random_int().
    • [RFC] var_representation(): readable alternative to var_export()
      Функция var_export(), которая выводит набор выражений в строку, давно была предметом жалоб. Как минимум был RFC с предложением сменить синтаксис массива с array( ) на [ ].

      Теперь же предлагается просто ввести новую функцию var_representation($value, int $flags=0) :string, которая исправит все недостатки var_export().

      В качестве альтернативы пока можно использовать brick/varexporter.
    • [RFC] Change Default mysqli Error Mode
      В рамках инициативы по улучшению расширения mysqli (подробнее было в PHPLive#3 ) предлагается первый шаг: сделать режим бросания исключений в случае ошибки дефолтным. То есть это как если сейчас в приложении добавить вызов: mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

      Из крупного опенсорса mysqli используют только CodeIgniter и WordPress.
    • [RFC] Dump results of expressions in `php -a` — На голосовании предложение по улучшению интерактивного шелла php -a.
    • PHP 8.1: What's New and Changed — На php.watch можно следить за тем, как будет выглядеть PHP 8.1. На сайте собраны все принятые RFC и важные пул-реквесты с описаниями.

    Инструменты


    • fabpot/local-php-security-checker — Проверяет composer.json на предмет наличия зависимостей с известными уязвимостями. В качестве базы уязвимостей используется FriendsOfPHP/security-advisories.

      Можно использовать готовый GitHub action или Docker-образы от oxcom.
    • funivan/PhpClean — Плагин для PhpStorm, который добавляет пачку интересных инспекций, например, чтоб везде были объявлены типы, не было лишних комментариев, и использовалась композиция вместо наследования. Отличный пост в поддержку.
    • wasmerio/wasmer-php — WebAssembly рантайм для PHP. Расширение позволяет запустить и использовать любой wasm-бинарник из PHP. То есть можно взять библиотеку на Rust, скомпилировать в wasm и использовать на любой платформе из PHP. При этом с очень высокой производительностью. Подробнее в посте автора.
    • temporalio/sdk-php — Антон Титов и Кирилл Несмеянов готовят PHP-SDK для temporal.io – распределенный, масштабируемый, отказоустойчивым, высокодоступный движок, для выполнения процессов бизнес-логики.

      Пример реализации накопительной транзакции т.е. перевести деньги продавцу от нескольких покупателей в течении какого-то периода времени:
      Скрытый текст
      #[Workflow\WorkflowInterface]
      class LoopWorkflow
      {
          private array $values = [];
          private array $result = [];
          private $simple;
      
          public function __construct()
          {
              $this->simple = Workflow::newActivityStub(
                  SimpleActivity::class,
                  ActivityOptions::new()->withStartToCloseTimeout(5)
              );
          }
      
          #[SignalMethod]
          public function addValue(
              string $value
          ) {
              $this->values[] = $value;
          }
      
          #[WorkflowMethod(name: 'LoopWorkflow')]
          public function run(
              int $count
          ) {
              while (true) {
                  yield Workflow::await(fn() => $this->values !== []);
                  $value = array_shift($this->values);
      
                  $this->result[] = yield $this->simple->echo($value);
      
                  if (count($this->result) === $count) {
                      break;
                  }
              }
      
              return $this->result;
          }
      }

      Под капотом RoadRunner, reactphp/promise, атрибуты PHP 8. Подробнее на стриме расскажет сам автор, Антон Титов.

    Symfony



    Laravel



    Yii



    Async PHP


    • walkor/Workerman — Асинхронный движок с простым API, поддержкой HTTP, WebSocket, SSL. Может работать в связке с libevent.

      Самый быстрый фреймворк на PHP в бенчмарках the-benchmarker/web-frameworks, в частности, потому что умеет из коробки стартовать пачку воркеров.

      Также на его базе есть реализация socket.io сервера walkor/phpsocket.io, адаптер PSR-7,15,17 chubbyphp/chubbyphp-workerman-request-handler, и фреймворк gotzmann/comet.

    Статьи



    Аудио/Видео



    Сообщество


    • habr Это не легаси-код, это PHP.
    • Буря в стакане по поводу PHP 8 — В декабре был пост от @jrf_nl, в котором автор жаловалась, что в PHP 8 слишком много обратно несовместимых изменений и обновиться очень сложно.
      Эту идею подхватил и Зеев Сураски, который играл одну из ключевых ролей в развитии PHP в период 1997-2017.


      В ответ Brent Roose написал свой пост и разложил, почему проблема преувеличена, а обновляться не страшно и лучше делать это регулярно.

      Хотя доля правды в словах Зеева и других есть. Потому что иногда миграция может быть неочевидной. Например, вот такой код никогда не вызывал ни ошибок ни депрекейшн ноутисов, а в PHP 8.0 отвалится с TypeError:

      var_dump(round("foo"));
      3v4l.org/pU0LD

      Или вот еще неочевидный, хоть и задокументированный, пример из слайдов:
      $sub = substr('abcdef', 4, -4);
      if ($sub === false) {
          echo 'fail';
      } else {
          echo 'do something with $sub';
      }
      
      // PHP 5-7 > 'fail'
      // PHP 8   > 'do something with $sub'
      
      3v4l.org/Ln9g3

      В тему хороший ресурс по обновлению и поддержке легаси кода: understandlegacycode.com.
    • Как выглядел бы PHP, если бы это зависело от меня — Подборка желанных фич от Brent Roose: final и void по умолчанию, никакого mixed, параметры и свойства обязательно типизированные, дженерики, куда ж без них, енамы, объекты для скаляров.





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



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

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

    Прислать ссылку
    Поиск ссылок по всем дайджестам
    Предыдущий выпуск: PHP-Дайджест № 196

    Комментарии 37

      +5
      mysqli используют только ...

      чуть менее 40% веб-сайтов всего мира ;-)
        0

        Это да :-) Кстати, пересекается с заметкой про обновление на PHP 8.0. Там как раз автор ссылается на то, что значительная часть пользователей PHP не разработчики (WordPress).

          +1
          Да, и недавно в комменте к моей статье показали еще одну проблему 8ки — 3v4l.org/rmN8l
          К сожалению, ни один статический анализатор эти проблемы не показывает.
          pronskiy, а есть ли планы добавить проверки потенциальных проблем с 8кой в PHPStorm?
            0
            Да, и недавно в комменте к моей статье показали еще одну проблему 8ки — 3v4l.org/rmN8l

            Это как раз вполне ожидаемое и документированное поведение https://wiki.php.net/rfc/string_to_number_comparison


            Есть на странице релиза https://www.php.net/releases/8.0/en.php#saner-string-to-number-comparisons и упоминалось в дайджестах 151, 185. Но согласен, что выглядит как то, что хотелось бы найти автоматически.


            pronskiy, а есть ли планы добавить проверки потенциальных проблем с 8кой в PHPStorm?

            Обсудим в команде, спасибо за наводку.

              0
              Конечно, это документированное поведение.
              Проблема вот в чем: если в функции/методе тип возврата — строка, любое сравнение результата вызова метода с 0, или при возврате int сравнение с '', или сравнение двух вызовов друг с другом в if, for, while, etc — это потенциальная ошибка, о которой узнать невозможно.
              К примеру, метод может возвращать результат запроса вида 'SELECT col FROM… LIMIT 1',
              +1

              Попробуйте задетектить это с помощью phpgrep. Должно получиться просто и быстро. Заодно можете сделать PR в общий список инспекций для этой утилиты.

                +2

                Да, phpgrep или в PhpStorm можно сделать поиск/замену/катомнуюинспекцию с помощью Structural Search and Replace.



                Только два шаблона поиска придется сделать: $string$ == $int$ и $int$ == $string$.

                  0
                  roxblnfk спасибо за подсказку, поэкспериментирую

                  pronskiy — а заодно и все комбинации с типом mixed, + switch case 0: )))
            0
            Никита предлагает сделать возможным использование объектов в качестве ключей обычных массивов.
            — кто то знает зачем это?
              +4
              Поводом для предложения послужил тот факт, что в RFC Enumerations предлагается сделать значения енамов объектами. И соответственно тогда их нельзя будет использовать в качестве ключей массивов. А это существенный минус.
                –3
                Но это не отвечает на вопрос зачем это. Чем дальше тем больше бесполезных изменений в языке делают
                  +5
                  Это возможность, которая не привносит минусов. Не нравится — не используйте
                0

                Чтобы хранить отбражение одних объектов на другие. Во всех нормальных языках нет ограничения на тип ключа в подобных коллекциях. Но да, для php это не нужно. :)

                  0
                  А что такое «нормальные языки»?
                    0

                    Языки, в которых есть нормальные коллекции, а не странные массивы. Желательно со статической типизацией.

                      0
                      В этом плане слово «нормальные» больше похоже на религиозную догму.
                        –1

                        Так я не настаиваю. :) Удивляйтесь дальше "предложениям Никиты". И не забывайте на ночь зубрить таблицы сравнения и приведения типов.

                  0

                  Какие-то карты составлять типа:


                  $found = [
                   $product1 => true,
                   $product2 => false,
                  ];

                  а не


                  $found = [
                   $product1->id => true,
                   $product2->id => false,
                  ];

                  а потом выгребать по id

                  +1

                  Yii Auth тегнули 3.0.0. В релизных новостях ошибка была.

                    0

                    Поправил, спасибо

                    0
                    PHP Russia переносится на 28 июня 2021 года.
                    Япония хотят отменить Олимпиаду, а организаторы «PHP Russia» все ищут дно короновируса D)

                    Опять для них не очевидны очевидные вещи!
                      0
                      организаторы «PHP Russia» в комменте выше тегнули Yii Auth и поправили статью ;-)
                      +1

                      Из больших игроков кто пользует mysqli
                      https://github.com/phpmyadmin/phpmyadmin/blob/master/composer.json
                      Я ещё на прошлом стриме говорил

                      0

                      Fibers в очередной раз никуда не попадает?.. жаль )

                        0

                        Откуда такая информация?

                          0
                          Предположение, т.к. нигде про него не пишут. Непонятно на какой стадии обсуждения по нему.

                          Файберы ведь уже пытались протащить в ПХП года три назад и смутные ощущения что история повторяется )

                          Есть другая информация?
                            0

                            Пишут и показывают еще как :-)
                            https://t.me/phpdigest/204
                            https://habr.com/ru/post/535308/
                            https://youtu.be/mvjj_YX_BqQ?t=539


                            Если коротко, то сейчас как никогда хорошие шансы, что добавят.

                              +1
                              Спасибо! «хорошие шансы, что добавят» — вот этой фразы нигде в явном виде не было, поэтому было недопонимание происходящего.
                        0

                        Роман, а вы смотрели в код вот этого вот?


                        walkor/Workerman — Асинхронный движок с простым API, поддержкой HTTP, WebSocket, SSL. Может работать в связке с libevent.

                        Тестов нет, мин.версия PHP 5.3, посмотрел по диагонали код — глаза не вытекли, конечно, но слезы проступили…
                        что это и зачем это в дайджесте?!

                          0

                          А вы текст дайджеста читали? Во втором параграфе описания указано зачем это в дайджесте.

                            0

                            А, ну то есть, если самый быстрый по бенчмаркам, то уже и не важно, что он без тестов, и з сомнительным качеством кода?! Окай, буду знать:))

                              0

                              Если самый быстрый, то значит, что заслуживает внимания.

                                0

                                Так ему уже скоро 10 лет как. Примерно как тому самому "пхпдемону". Такое же "протестированное временем" решение, как и какая-нибудь phpmyadmin.

                            0
                            Про temporal кто-то может подсказать, что можно почитать детальнее case study про миграцию в рамках своего легаси-приложения: был, значит, сайт на php с многообразным функционалом и вдруг мы поняли что можем все переписать(?) на temporal или встроить его в процесс?
                              +1

                              Рекомендую зайти в официальное комьюнити temporal: https://community.temporal.io/


                              На практике все переписать не получится, но изолировать часть процессов — без проблем. Для начала нужно выделить части бизнес логики в виде activity: https://docs.temporal.io/docs/activities (в них можно записать большую часть легаси кода)


                              А после смотреть на реализацию workflow сверху: https://docs.temporal.io/docs/workflows

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое