PHP-Дайджест № 162 (1 – 12 августа 2019)


    Свежая подборка со ссылками на новости и материалы. В выпуске: О будущем PHP: P++ или PHP2020, принят PSR-12, PHP 7.4 beta 2, Slim 4, и другие релизы, порция полезных инструментов, и многое другое.

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



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



    PHP Internals


    • P++ — Споры и обвинения в PHP Internals по мотивам удаления коротких тэгов <?, явной передаче параметров по ссылке и других обсуждений в конце концов вылились неожиданное предложение от Зеева Сураски – сделать новый диалект PHP. Рабочее название P++ тут неспроста – Зеев предлагает сделать «сестринский» язык, как C++ для C. При этом предполагается, что и PHP и P++ будут развиваться одновременно в рамках одного рантайма.

      В новом P++ можно будет реализовать массу революционных улучшений, очистить от легаси, и навести порядок не думая об обратной совместимости. Также поскольку язык будет иметь новое название, то и от шлейфа плохой репутации можно будет отделаться. A классический PHP при этом будет получать все плюшки типа JIT, предзагрузки, и т. п., но сохранять обратную совместимость.

      Предложение ожидаемо встретило массу контраргументов и Зеев даже попытался ответить на них создав P++ idea: FAQ. Тем не менее, вопросов множество: ограниченные ресурсы (всего ~2 человека фултайм работащих над PHP), фрагментация сообщества, опыт Hack, как реально будет сосуществовать и взаимодействовать код PHP и P++, и масса других.
    • [RFC] Namespace-scoped declares, again — В рамках RFC Никита Попов предлагает более эволюционный подход по дальнейшему развитию языка. А именно, использование опциональных директив по типу strict_types.
      Причём тут есть два возможных пути реализации: мелкозернистый – по директиве на каждую фичу; и крупнозернистый – когда целая пачка фич объединяется в одну директиву обозначающую редакцию или стандарт языка, например «PHP2020». По аналогии с Editions из Rust.
    • Call for participation: Annotating internal function argument and return types — Хотите стать контрибьютором ядра PHP? Более подходящего момента для старта не придумаешь!
      Недостаточная информация о внутренних функциях в Reflection – довольно старая проблема. К счастью, в PHP 8 уже всё готово для того, чтобы сделать поддержку типов для аргументов и возвращаемых значений встроенных функций. Собственно, осталось только добавить соответствующие аннотации и для этого нет необходимости быть экспертом в С. Никита сделал PR с примером, чтоб показать процесс: https://github.com/php/php-src/pull/4499 Ну а дальше – помощь приветствуется!

    Инструменты


    • nunomaduro/pest — Синтаксический сахар для PHPUnit, чтобы писать тесты в стиле facebook/jest.
    • php-vcr/phpunit-testlistener-vcr — Записывает HTTP-ответы в ваших тестах и затем «проигрывает» их во время последующих запусков тестов, тем самым ускоряя запуски и детерминируя результат. Пример использования.
    • mpratt/Embera — Библиотека для удобного получения метаинформации о страницах по URL (oembed, opengraph, twitter-cards, изображения, код для встривания и прочее).
    • NxtLvLSoftware/php-static-constructors — Статические конструкторы а-ля C# – исполняются максимум один раз. Реализованы через специальный автозагрузчик.
    • DaveLiddament/sarb — Реализовывает Baseline для инструментов статического анализа, позволяя внедрять использование в легаси-приложениях.

    Symfony



    Laravel



    Yii



    Async PHP



    Материалы для обучения




    Аудио/Видео



    Спасибо за внимание!

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

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

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

    Поделиться публикацией

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

      +2

      В очередной раз спасибо за дайджест!


      Немношк актуализации:


      Slim 4.0.0

      Почти следом, 6 августа, вышел релиз 4.1.0

        +1
        Спасибо за очередной дайджест. Каждый раз нахожу что-то интересное.
        Хотелось бы добавить свои пять копеек, для тех, кто использует связку Phalcon + Redis.
        Во время последнего обновления до php7.3.8, обновился и модуль php-redis до версии 5.02. И в этом обновлении метод redis->settimeout признан deprecated, с рекомендацией использовать метод redis->expire. Соответственно если хотим обновиться до выхода новой версии Phalcon – можно/нужно поправить Phalcon\Cache\Backend\Redis->_connect. А если используете сессии на Redis то еще и в конструкторе Phalcon\Session\Adapter\Redis->__construct в качестве redis указать обновленный Phalcon\Cache\Backend\Redis

        Думаю, лучше продемонстрировать кодом:
        SessionAdapterRedis.php
        namespace Kernel\Extend;
        
        use \Kernel\Extend\CacheBackendRedis as Redis;
        use \Phalcon\Cache\Frontend\None as FrontendNone;
        
        class SessionAdapterRedis extends \Phalcon\Session\Adapter\Redis  {
        
          public function __construct(array $options = []) {
        
            if(!isset($options['host'])) {
              $options['host'] = '127.0.0.1';
            }
        
            if(!isset($options['port'])) {
              $options['port'] = 6379;
            }
        
            if(!isset($options['persistent'])) {
              $options['persistent'] = false;
            }
        
            $lifetime = $options['lifetime'] ?? null;
            if($lifetime) {
              $this->_lifetime = $lifetime;
            }
        
            $this->_redis = new Redis(
              new FrontendNone(['lifetime' => $this->_lifetime]),
              $options
            );
        
            session_set_save_handler(
              [$this, "open"],
              [$this, "close"],
              [$this, "read"],
              [$this, "write"],
              [$this, "destroy"],
              [$this, "gc"]
            );
        
            $this->setOptions($options);
          }
        }

        CacheBackendRedis.php
        <?php
        namespace Kernel\Extend;
        
        use \Library\Redis;
        use \Phalcon\Cache\Exception;
        
        class CacheBackendRedis extends \Phalcon\Cache\Backend\Redis {
        
          public function _connect() {
        
            $host = $this->_options['host'] ?? null;
            $port = $this->_options['port'] ?? null;
            $persistent = $this->_options['persistent'] ?? null;
        
            $redis = new Redis;
        
            if(!$host || !$port || is_null($persistent)) {
              throw new Exception("Unexpected inconsistency in options");
            }
        
            if($persistent) {
              $success = $redis->pconnect($host, $port);
            } else {
              $success = $redis->connect($host, $port);
            }
        
            if(!$success) {
              throw new Exception("Could not connect to the Redisd server ". $host .":". $port);
            }
        
            $auth = $this->_options['auth'] ?? null;
            if($auth && !empty($auth)) {
              $success = $redis->auth($auth);
        
              if(!$success) {
                throw new Exception("Failed to authenticate with the Redisd server");
              }
            }
        
            $index = $this->_options['index'] ?? null;
            if($index && $index > 0) {
              $success = $redis->select($index);
        
              if(!$success) {
                throw new Exception("Redis server selected database failed");
              }
            }
        
            $this->_redis = $redis;
          }
        
        }
        

        Redis.php
        <?php
        namespace Library;
        
        class Redis extends \Redis
        {
          public function settimeout($lastkey, $tt1) {
            return $this->expire($lastkey, $tt1);
          }
        }

          0
          Спасибо за дайджест! Идея с P++ такое себе) Мне нравится подход с declare, хочешь включаешь типизацию, хочешь — нет. Но еще больше мне нравится подход, как с тем же Angular, выходит новый фреймворк, обновляей систему или сиди на старой. Не вижу проблем, почему нельзя выпускать новые релизы PHP, без саппорта легаси, пусть легаси сидит на старых версиях.
            +1

            если будет выбор новые версии с легаси или P++ я бы выбрал второе)

              +4
              Вероятно, мсье никогда не работал с проектом с кодовой базой возрастом 15+лет
              0
              В новом P++ можно будет реализовать массу революционных улучшений, очистить от легаси, и навести порядок не думая об обратной совместимости

              Ну наконец-то! Я думаю всем языкам со временем так надо делать (например каждые 20 лет), ато из-за проблем обратной совместимости, с годами накапливается просто куча мусора в кодовой базе, от которого никак не избавиться.

              Ну или как сказал коллега выше, не поддерживать обратную совместимость в каждой новой мажорной версии.
                0
                Действительно создание нового языка P++ на базе PHP выглядит сомнительной затеей
                  0

                  Почему же?

                    0

                    не потянут. ресурсов и на актуальный php не хватает.

                      0
                      Так уважаемый комментатор высказался что создание языка на базе PHP выглядит сомнительной затеей, а не что сомнительно потому что ресурсов нет. Видно он знает что-то такое что помешает родиться хорошему языку(одному из тысяч :)).
                  0
                  А зачем нужна вся эта история с получением доступа к приватным пропертям без рефлексии? Каков use case использования этого трюка в реальном продакшене?
                    +1

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


                    p.s. Да-да, я знаю, что если очень хочется так сделать, то что-то не так с архитектурой и тестировать надо публичный контракт класса, а не его кишки, но жизнь штука многогранная и иногда приходится делать и такие трюки.

                      0
                      Спасибо за развернутый ответ! Про тестирование приватных пропертей я понял. Только почему именно «без рефлексии»? Мы тестируем что-то в PHP 4, где нет рефлексии? Ну так там и нету closures! «Рефлексия — это медленно!». Лишняя секунда (ок, 10 секунд!) на выполнение тестов причиняет такие велики боль и страдания, что надо вот заморачиваться с хитрыми трюками? Это не к Вам, levchik, вопрос. Это так просто, мысли вслух. Еще раз спасибо за ответ!
                        0

                        Думаю, что это просто один из подходов решения проблемы, а уж что использовать — выбирает каждый сам для себя. Мне тоже ближе использовать замыкания, чем рефлексию, не потому что быстрее или еще что-либо, а просто потому что больше нравится запись.

                        +1
                        Для меня есть один валидный повод тестить с использованием рефлексии — это если тестируемый код работает с использованием рефлексии. Например какие-нибудь хитрые дата-мапперы или десериалайзеры, которые устанавливают значения напрямую в проперти. В этом случае вполне валидно подсмотреть рефлексией, что там установлено
                        +2
                        Рефлексия, принципиально, используется в (почти) любом языке ровно 2мя способами:

                        1) Для написания (не самых лучших) тестов. Оно же — для тестирования кода, на который до этого не писали тесты.

                        2) Для реализации магии (/синтаксического сахара) которую нельзя реализовать обычным синтаксисом. В мире пыха два основных столпа — аплоад даты в ентити доктриной и аннотации (кстати, тоже доктрина).

                        В некоторых случаях встречается код который представляет оба пункта. Например — моки.
                          0

                          Весь autowire тоже построен на рефлексии.

                            +1
                            Мое мнение что autowire — как раз пример второго случая (магия). Если нам не нужет DI с какой-то логитой (теги, выбор инджекта по условиям) — то autowire это синтаксическая магия. Используй интерфейс в конструкторе и получи сразу сбилженный сервис.
                          0
                          1. Тестирование.
                          2. Гидрация.
                          +1
                          > опыт Hack

                          как раз успели обсудить на первом Харьков Beer
                            0
                            Подскажите как помочь с добавлением соответствующие аннотации? Есть желание, но чот не пойму как я могу помочь)
                              +1
                              > P++

                              Можно долго обсуждать, но фундаментально проблема легко формулируется. А через 5-10 лет будем делать Q++?

                              Для примера. Уже через 10 лет от С++ (85->95) появилась Джава чтобы улучшить уже плюсы.
                                0
                                Хотя должен заметить что я яро поддерживаю и Попова и Сураски. Легаси надо как-то контролировать и выпиливать.
                                  +1
                                  Может я что-то упускаю, но мне кажется что говорить что Java это продолжение С не совсем корректно. Все же Java подразумевает дополнительный слой в виде JVM чем обеспечивается кроссплатформенность и универсальность кода. В то время как С и С++ классические компилируемые языки подразумевающие возможность написания кода под определенный процессор и вообще железо с соответствующим уровнем понимания всех нюансов как аппаратной части так и логической (к примеру сборка мусора).
                                  А что насчет P++ -> Q++ это вкусовщина. Не так уж и важно что и как мы называем, главное чтобы было понятно как и зачем с этим работать. Когда Расмус начал писать PHP он не думал и не мечтал что эта поделка превратится в полноценный язык программирования и будет так востребован через 25 лет. Что будет еще через 10 — время покажет.
                                  Мне кажется не стоит обосновывать сегодняшние решения какими-то абстрактными аргументами. Есть вполне конкретные аргументы почему хочется сделать отдельный диалект и есть аргументы почему это не так просто как хотелось бы. Было бы просто, вопрос бы не стоял. И основной вопрос это в первую очередь ресурсы.
                                  Ресурсы найдутся я думаю только если кто-то большой скажет что ему это нужно. Но я в этом сомневаюсь. К сожалению, последние лет 5, несмотря на прорыв с PHP 7, индустрия в целом не смотрит на PHP. Все ушли в Java, Python, NodeJS, Go etc. PHP не спеша, но закапывают в землю. Это грустно наблюдать. Поэтому я думаю у ребят не хватит сил поднять и тащить еще один диалект. Думаю они все же просто станут отрезать легаси в основной ветке с каждым релизом. Этого достаточно для коммьюнити.
                                    –1
                                    Коммьюнити, а именно сами разработчики, не хотят вырезать легаси. Это хотят лишь некоторые больные на голову мазохисты/максималисты/шизофреники, которым не надо поддерживать тонны работающего кода.
                                      +1
                                      Я разработчик. Я хочу вырезать легаси. Возможно я «больные на голову мазохисты/максималисты/шизофреники». Но мне кажется я просто не такой как вы. Может не стоит разбавлять свою речь опосредованными ярлыками не подтвержденными профессиональным мнением и техническими аргументами?
                                      Вы заодно походя оскорбили основную команду разработчиков и ментэйнеров, которые отрезали огромную часть легаси при переходе на PHP 7 и явно не собираются сдаваться и менять свое мнение в этом направлении.
                                      А насчет тонн работающего кода, зачастую при наличии воли, рефакторинг занимает не так много времени и позволяет начать экономить время и ресурсы вообще. Не так страшен черт как его малюют.
                                        0
                                        Да в гробу 95% разработчиков видели все эти переделки ради мифической «красоты». Работает — не трожь.
                                        Есть такие золотые слова «обратная совместимость». И в энтерпрайзе это особенно важно.
                                        То что горящие пылкие юноши мечтают каждый год всё переписывать заново и бесплатно (если это свои проекты, или рабочие, но это никто не оплатит), потому что всё сломалось и обратной совместимости нет — что ж, пусть занимаются этим мазохизмом, только пожалуйста в другом языке.
                                          +1
                                          Повторюсь, мы с вами разные. И стиль вашего изложения скорее подходит к «горящие пылкие юноши». А ко мне это как раз не относится, вы уж извините, но я уже давно не юноша. Так что ваши эмоциональные вставки снова разбиваются о реальность. Нелюбовь к легаси и любовь к стройности кода, скорее все же присуща опытным и грамотным разработчикам, чем юношам. И снова, как пример, команда разработчиков PHP. Их тоже трудно назвать юношами и уж тем более пылкими.

                                          Попытаюсь донести до вас свою позицию. И в чем она отличается от вашей. Отбросив эмоциональные и бессмысленные по сути высказывания имеем ваш аргумент:
                                          … переделки ради мифической «красоты». Работает — не трожь.
                                          … «обратная совместимость».

                                          Отвечаю по пунктам:
                                          Ради мифической красоты не надо ничего переделывать. Если вы или я не знаю зачем я что-то переделываю, то я с вами тут легко соглашусь, не надо ничего переделывать. Но на практике вы или такие как вы, или то как я понимаю кто вы :-) используют этот аргумент чтобы «ничего не трогать». Например имеем спагетти модели данных или даже то что трудно назвать моделями, все написано в разное время разными разработчиками, какие-то куски похожи друг на друга, какие-то нет. И трогать эту всю «красоту» никому не хочется. Только вот на мой взгляд стОит это переписать чтобы все было понятно и однообразно и желательно с использованием лучших паттернов программирования и с учетом требований безопасности. Потому что это сократит время на onboarding, сократит время на отладку и отлавливание любых видов багов, позволит применять нормальные методы тестирования и учета зависимостей, увеличит производительность, и в итоге сократит расходы на поддержание в разы, а может и в десятки раз. Так же хороший код позволяет притягивать и удерживать грамотных специалистов в проекте и поднимать уровень молодежи, которая впитывает бест практисес каждый день, вместо того чтобы привыкать и считать что легаси — это норма. И упаси боже если молодежь решит что (подставлять костыли повсюду) это лучшее что они могут делать в их жизни.
                                          Работает — не трожь. Тот же ответ что и с предыдущим пунктом. Я полностью согласен, что если что-то работает — не надо это трогать. Только в жизни зачастую люди считают что-то неработающее чем-то работающим. И чаще всего все это легаси не работает, а перманентно глючит и команда постоянно отвлекается и занята поиском причин почему оно глючит или отваливается раз в неделю. видал я такие проекты где решением была перезагрузка сервера по ночам, чтобы не искать причину таких глюков. Так что да если что-то работает, трогать не надо, а вот если к вам второй раз пришел запрос на поиск причин инцидента с какой-то подсистемой и вы знаете что истинная причина кроется в легаси, то я бы поднимал вопрос и начинал планировать рефакторинг.
                                          обратная совместимость Не совсем понимаю о чем вы. Все паттерны известны и нет никакой проблемы с обратной совместимостью PHP кода. Есть недостаток знаний и опыта как это правильно мигрировать.
                                          Но вы можете оставаться при своем мнении. Дело хозяйское. Просто меня цепляет ваша категоричность и эмоциональность. Особенно отсылка к «пылким юношам», как-то смешно звучит.
                                            0

                                            Вот у меня другие ощущения, что 95% хотели бы убрать легаси. И лишь 5% ретроградов прикрываясь глупостью "работает — не трожь" ничего не хотят делать.
                                            https://externals.io/message/106453#106477 — скорее всего, большинство будет солидарно с этим письмом.

                                              +1
                                              >>lot of people ended up quite happy after doing the upgrades
                                              Спасибо, посмеялся. Люди были бы happy после upgrades, если бы у них никогда ничего не ломалось, а просто добавлялась бы производительность и новые возможности. В нормальном энтерпрайзе так и должно быть. PHP же стараются постоянно сместить на дорожку несовместимости Python 2/3.

                                              >>Tooling was available to automate transitions.
                                              Спасибо, тоже посмеялся. Куча разразнённых тул, ни одной полностью официальной, и всё равно находит лишь часть несовместимостей. Например ни одна тулза даже не знала о поломке htmlspecialchars в 5.4, когда для кириллициы оно по дефолту начало возвращать пустоту. Ни одна тулза не имеет автоматического режима с одной кнопкой FixAll, которая бы сама гарантированно и работоспособно всё исправила, а значит требуется всё равно много времени ручного труда, дебага, проверок и тестов.

                                              Я согласен с его высказыванием, что нет смысла удалять <?, потому что и так есть short_tags=off для тех кто это не хочет.
                                                0
                                                Не совсем понял вашу позицию, так как это письмо как раз против P++ (по крайней мере то, что прямо по ссылке).

                                                Если я правильно понимаю, P++ как раз не ломает обратную совместимость. Здесь похоже на связку Java + Kotlin: вы можете пользоваться Legacy-библиотеками, но при этом свой проект уже писать на новом диалекте. При этом, переводить на новый диалект проект можно будет поэтапно. И наоборот: можно писать на старом PHP, но использовать при этом новые библиотеки на P++.

                                                Это вполне может получиться, но зависит от «вкусности» нового диалекта для разработчиков. Например, меня может соблазнить переработка стандартной библиотеки, и например замена стандартных функций работы с массивами на что-то типа [1,2,3].push(4).

                                                Но рисков тоже очень много.
                                                  0

                                                  P++ был бы хорош, если бы на него были ресурсы. А на него ресурсов нет.
                                                  Соответственно, видятся варианты в виде LTS или настроек вроде declare(strict_types=1)/short_tags = On/Off.
                                                  Но то, что php отстает от мейнстрима все сильнее — очевидно, и с этим надо что-то делать.

                                                  +1
                                                  К сожалению в мире пыха это не соответсвует реальности. Легаси таки больше. Проектов где хотят легаси — больше. Так что многие разработчики, что хотят и могут писать более строго, ограничены. Иногда даже тупо старыми версиями пыха и окружения.

                                                  Лично я за выкидывания легаси и максимально строгие правила внутри проекта\модуля. Но без гиганстской работы (уровня мажорного релиза) по совмещению того и другого — общество в конце выкинет решение без обратной совместимости.
                                            +1
                                            > А что насчет P++ -> Q++ это вкусовщина

                                            имелся в виду третий диалект.

                                            > но мне кажется что говорить что Java это продолжение С не совсем корректно

                                            Это уже детали. Не важные в контексте разговора. Что важно — когда с++ стукнуло 10 очень многие хотели избавится уже от его легаси (а не 20 летнего с) новым (третим) языком.

                                            > Мне кажется не стоит обосновывать сегодняшние решения какими-то абстрактными аргументами.

                                            Диалект — одно из многих возможных решений борьбы с легаси. Мое личное мнение — одно из худших. Но если все другие способы отметут и останется диалект ВС оставить все как есть — я буду за диалект.
                                          0
                                          Посоветуйте пожалуйста что нибудь дельное почитать о перезагрузке, очень заинтересовало. Кто уже применяет в реальных условиях?
                                            0

                                            Думаю, не сопротивлялись бы и добавили возможность внедрять код напрямую в Zend VM — появилась бы куча уже диалектов (привет JVM). Само появление Hack Lang — это одна из причин отсутствия оного функционала.


                                            А то в текущем варианте можно лишь патчить опкеш, что является чуть-чуть извращением. Ну и переписывать/кодогенерировать сырцы (Yay, Preprocess, Symfony, Doctrine, Go!, e.g.).

                                              0
                                              А в чем сопротивление? Это же все опенсорс. Вроде каждый может делать все что ему вздумается.
                                                0
                                                появилась бы куча уже диалектов

                                                Вы так говорите, будто это что-то хорошее.

                                                0
                                                «История одного бага в Laravel Shift» — не история одного бага, а просто подборка фишек.
                                                  0
                                                  Поправил, спасибо за замечание!
                                                  0
                                                  навести порядок не думая об обратной совместимости

                                                  не сильно заметно, чтобы о ней много думали ранее.

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

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