Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 Alpha 1, свежие предложения из PHP Internals, Symfony 3.3.0, Yii 1.1.19 и 2.0.12, нововведния Laravel 5.5, спор о Visual Debt и многое другое. Приятного чтения!



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




PHP


  • Короткий синтаксис для анонимных функций — В Internals активно обсуждается возможная реализация коротких лямбд. Ранее рассматривался и был отклонен на голосовании синтаксис с тильдой: $x ~> $x + 1;, а также ^($x) => $x + $y. На данный момент рассматриваются следующие возможные варианты:

    fn(params) => expr
    function(params) => expr
    (params) ==> expr
    (params) => expr
    [](params) => expr
    

  • Включить PCS в ядро — Предложение для PHP 7.3 пока не оформленное в официальный RFC. PCS — это модуль, который позволяет писать расширения для PHP на PHP и С одновременно. Подробнее о PCS. Включение такой возможности в ядро позволит переписать многие расширения на PHP. Это, в свою очередь, позволит сильно упростить код, уменьшить число багов, и увеличить количество потенциальных ментейнеров.

Инструменты


  • reactphp/http v0.7.0 — HTTP/HTTPS сервер на базе ReactPHP.
  • hollodotme/fast-cgi-client — FactCGI клиент для отправки (а)синхронных запросов в PHP-FPM. Слайды, примеры использования с Redis и с RabbitMQ.
  • samdark/hydrator — Извлечение данных и заполнение данными объектов. Пост в поддержку.
  • phunkie/phunkie — Набор структур для функционального программирования на PHP. Туториал в поддержку.
  • gilbitron/sqsd — Демон эмулирует работу Amazon SQSD на локальной машине.
  • formapro/pvm — Библиотека для описания схемы процесса (workflow). Поддерживает асинхронные переходы и параллельное выполнение задач.
  • Composercat — Десктопное GUI приложение для Composer.
  • php-enqueue/enqueue-dev — Очередь сообщений с поддержкой транспортов AMQP (RabbitMQ, ActiveMQ), STOMP, Amazon SQS, Redis, Doctrine DBAL, Filesystem.

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



Занимательное


  • joaoescribano/UltimaPHP — Сервер популярной некогда игры Ultima Online на PHP.
  • 6 файлов, которые являются валидным PHP — GIF, PDF, JPG, которые можно выполнить как PHP.
  • Тайпхинты и интерфейсы — визуальный шум? — Jeffrey Way опубликовал видео, в котором рекомендует удалить тайпхинты, интерфейс, и объявление final, называя их визуальным шумом. На что получил ряд критических ответов, например тут, тут, и тут. Энтузиасты даже создали специальный инструмент статического анализа для поиска «визуального шума» — phpvisualdebt.

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

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

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

Поделиться с друзьями
-->

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


  1. malinichev
    12.06.2017 10:09
    -1

    Что-то относительно мало ссылок, или мне так кажется?


    1. pronskiy
      12.06.2017 11:00
      +1

      В среднем в дайджестах бывает 50-70 ссылок, сейчас ближе к 50


  1. andrewnester
    12.06.2017 10:34
    +1

    Сейчас идёт голосование за интересное RFC — сделать последовательными индексы в массивах, формируемых функциями array_*
    https://wiki.php.net/rfc/negative_array_index

    Вкратце — скорее всего, не попадёт в PHP 7.2, но возможно будет в PHP 8


  1. olegl84
    12.06.2017 12:52
    +4

    Вышла бета версия yii2 плагина для IDEA/PhpStorm.
    Скачать можно из закладки Beta на https://plugins.jetbrains.com/plugin/9388-yii2-support
    или по этой ссылке .

    Из нового:
    Автокомплит для правил валидации
    Автотип для Yii::createObject

    Прошу помочь с бета тестированием. Баги пишите в гит хаб: https://github.com/nvlad/yii2support


  1. myrkoxx
    12.06.2017 15:31

    Прошел PHP-FWdays в Киеве. Обещают поделиться видео через одну/две недели. Скорей всего к следующему дайджесту появятся


  1. GraDea
    12.06.2017 16:03

    Кто-то может новичку PHP объяснить смысл https://wiki.php.net/rfc/parameter-no-type-variance

    В наследнике появляется возможность забить на тип аргумента в родителе (то есть мы расширяем). В комментах к пуллреквесту срач насчет нарушает ли контрвариация аргумента LSP или нет (вроде как нет). Но у меня вопрос — зачем? Даем пользователям библиотек продолжать использовать свои бестиповые наследники?


    1. Nahrimet
      12.06.2017 21:32
      +1

      Я не могу себе придумать практическое применение этого вброса, который почти наверняка будет вести к нарушению LSP и OCP. Хочу схватиться за голову и бегать…


      1. pbatanov
        13.06.2017 11:28

        Как раз таки этот «вброс» ведет к частично более полному соблюдению LSP, в этом и суть.

        Если кратко, то LSP состоит в том, что множество допустимых входных параметров вы можете только расширять, а множество возможных выходных параметров вы можете только сужать.

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


        1. Nahrimet
          13.06.2017 12:59

          Откровенно говоря, Ваше краткое определение LSP тоже заставляет хвататься за голову и…


          1. pbatanov
            13.06.2017 14:39

            А я не говорил, что это определение. Это одно из следствий со стороны обсуджаемого вопроса.

            Если вы хотите строго по определению, то пожалуйста. Представьте, что у вас есть тип T с методом T::f(A $a). И есть тип S extends T с методом, который отличается только отсутствием тайпхинта S::f($a).

            Если сам код методов идентичен, то если свойство q(T x) верно, то и свойство q(S y) тоже будет верным

            Таким образом исключение тайпхинта не нарушает LSP, а текущее поведение (фатал парсера) — нарушает. Что подтверждает мое утверждение

            ведет к частично более полному соблюдению LSP


            1. Nahrimet
              13.06.2017 22:12

              Во-первых, старайтесь никогда не приводить примеры абстрактных коней в вакууме, так как они за собой влекут точно такие же выводы.
              Во-вторых, Вы на основе чего программируете? Реализации? Не ведет это «к частично более полному соблюдению LSP». Если сигнатура гласила Razor::shave(Beard $beard), то, для возможности побрить что-то еще, необходимо не глушить сигнатуру в дочернем классе, а пересматривать решение на уровне интерфейса. Почему не, к примеру, Razor::shave(ShaveableInterface $hairySurface)?

              Вы не подумайте, я на Вас бочку не качу)
              Просто не в состоянии своё недоумение выразить в полной мере касательно «parameter-no-type-variance». Только и просится фраза «Зачем?!».


              1. Fesor
                13.06.2017 23:05

                Только и просится фраза «Зачем?!»

                Все началось с какого-то обсуждения в internals где предлагали что-то пофиксить но для того чтобы не ломать обратную совместимость пришлось ваять этот RFC. Все как обычно.


              1. pbatanov
                13.06.2017 23:24

                Основная проблема в том, что контр\ковариантность в пхп пока не смогли, потому что это создает какие то проблемы в разработке енамов.

                то если у Razor есть наследники (положим, это библиотека), то изменить сигнатуру указанным образом невозможно, это тут же нарушает LSP для наследников.

                Если же сделать нового «правильного» наследника, с нужной сигнатурой, то текущая версия PHP кидается ворнингами (т.к. пока мы живем с инвариантами)

                https://externals.io/thread/514
                https://wiki.php.net/rfc/return_types#variance_and_signature_validation

                Так что это полумера, но это единственное что позволяет перейти от одного интерфейса к другому с сохранением обратной совместимости и без особых костылей. Хотя если вы знаете короткий путь, то готов посмотреть


      1. LastDragon
        13.06.2017 13:17

        Да легко оно представляется, особенно когда есть куча старого кода, который надо поддерживать и рефакторить, более того, в самом rfc об этом написано и даже приведено несколько реальных примеров.


    1. masterjus
      13.06.2017 11:57

      Суть предложения в том, что если у предка указан тайпхинт, то потомок может уже не писать его, он будет взят из предка
      По крайней мере я так это понял


      1. GraDea
        13.06.2017 12:43

        В комментах указано

        // This RFC proposes allowing the type to be widened to be untyped aka any
        // type can be passed as the parameter.
        // Any type restrictions can be done via user code in the method body.
        


        То есть ограничения снимаются и дело не просто в отсутствии варнинга.


  1. kirill-m
    12.06.2017 16:11
    +1

    Огромное спасибо!


  1. Bolotov_Nikita
    12.06.2017 21:16

    всегда с удовольствием читаю. спасибо.


  1. igordata
    13.06.2017 07:24

    Спасибо! Всегда читаю этот дайджест.

    6 файлов, которые являются валидным PHP — GIF, PDF, JPG, которые можно выполнить как PHP.

    Примажусь по случаю Как запустить *.jpg как *.php или как предотвратить исполнение загруженных юзером файлов


  1. GraDea
    13.06.2017 08:36

    И про тоже интересно зачем.

    В примере есть код:

    class WidgetFactory {
        function create() {
            return new Widget();
        }
    }
     
    class CustomWidgetFactory extends WidgetFactory {
        function create() {
            $object = new Widget();
     
            return true; //This is an error that cannot be statically analyzed.
        }
    }
    


    Что мешает указать у метода create (): Widget?
    Ну помешает вернуть true спецификатор: object, но что делать с остальными объектами, которые несовместимы с Widget?


    1. GraDea
      13.06.2017 09:03

      Выше про object typehint вопрос.


  1. GraDea
    13.06.2017 11:21

    Подскажите, что в RFC значит Accepted — Pending Implementation?


    1. Corpsee
      13.06.2017 11:36

      Одобрен, но ожидает реализации в коде.


      1. GraDea
        13.06.2017 11:40

        То есть object typehinting скорее всего не ждать в 7.2? И вообще не факт, что оно дойдет до реализации в таком виде?


        1. Corpsee
          13.06.2017 11:43
          +1

          Видимо да. 7.2 уже в альфе, вряд ли там будет что-то новое.


          1. pronskiy
            13.06.2017 11:54

            Pull request есть https://github.com/php/php-src/pull/2080
            Думаю скоро смержат в master


  1. Elfet
    14.06.2017 15:10
    +1

    Надеюсь это будет


    (params) => expr


    1. morozovsk
      14.06.2017 16:27

      тоже подумал, что не плохо было бы сделать как в js, но этот вариант не просто так запихнули на предпоследнюю позицию

      //пример
      $param = 5;
      [
      	($param) => $param*2
      ]
      
      //может восприниматься парсером так:
      [$param => $param*2] //[5 => 10]
      
      //или так
      [
      	function($param) {return $param*2}
      ]
      

      скорее всего выберут fn


      1. Elfet
        14.06.2017 16:33

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


        [($param => $param*2)]


        1. morozovsk
          14.06.2017 16:44

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

          а в вашем примере благодаря скобкам что получится массив или функция?


          1. Elfet
            14.06.2017 16:45

            Думаю должно быть очевидно что [func]


            1. morozovsk
              14.06.2017 16:50

              понятно, я неправильно прочёл фразу «хочешь однозначности в массиве? — оберни в скрбки», думал что вы подразумеваете массив, хотя там должна быть функция


      1. Fesor
        14.06.2017 16:58

        скорее всего выберут fn

        function fn() {
            // bad ass
        }
        
        [fn($x) => $x ** 2]

        то есть все те же проблемы и еще большая обратная несовместимость. С другой стороны....


        [
            ($x => $x**2)
        ]

        уже будет нам говорить что это массив выражений. Скобки неплохой вариант устранения двусмысленности с точки зрения синтаксиса. Вот только парсеру это не помогает особо и этот вариант все равно остается сложным. Ну мол что бы было кошерно надо как-то по первой лексеме понять что у нас тут лямбда.


        Потому скорее уж примут function ($x) => $x ** 2.


        1. morozovsk
          14.06.2017 17:14

          теперь понятно для чего они добавили второй и третий варианты

          вообщем будем ждать голосования


          1. Fesor
            14.06.2017 17:21

            Пока страждущие могут пользоваться фолдингом в IDE:


            https://plugins.jetbrains.com/plugin/8477-php-lambda-folding


        1. LastDragon
          14.06.2017 17:45

          Потому скорее уж примут

          Почему не (params) ==> expr? Оператор ==> еще свободен, да и набирать не сильно сложнее чем =>.


          1. Fesor
            14.06.2017 19:45

            еще свободен

            1. потому что проблема не в двусмысленности, ее устраняют скобки. Идея в том что бы поменьше операторов добавлять, хотя с другой стороны идея так же что бы одни и те же операторы сохраняли свой смысл вне зависимости от контекста чего не происходит с =>.
            2. потому что профита с точки зрения реализации парсера это не добавляет.
            3. потому что => лучше чем ==> или ~>.


            1. LastDragon
              14.06.2017 20:05

              1. Новый оператор как раз в стиле PHP
              2. Отследить контекст ему проще?
              3. Хз, тильда непривычна, [](params) как-то странно выглядит, а function ($x) => совсем не короткий и оттого бессмысленный вариант. ИМХО, выберут между => и ==>.


              1. Fesor
                14.06.2017 20:13

                2 нет. PHP юзает LR(1) парсер, то есть "не двусмысленно" это когда он может понять что он парсит смотря максимум на одну лексему вперед. Так что "просто" это когда у нас есть кейворд в самом начале выражения. Типа fn или function. Тогда парсер запросто все обработает.


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


                3 Между этими вариантами нет смысла что либо выбирать на самом деле. fn удобно и хороший компромис но вводит новое ключевое слово (обратная совместимость). function — длинно, хотя по факту не то что бы сильно:


                $items = array_map(function ($row) => $this->hydrator->hydrate($row), $rows);
                $total = array_reduce($items, function ($sum, $item) => $sum + $item->price());
                
                // vs
                
                $items = array_map($row => $this->hydrator->hydrate($row), $rows);
                $total = array_reduce($items, ($sum, $item) => $sum + $item->price());


                1. LastDragon
                  14.06.2017 20:29

                  Вот именно что длинно, по сути только return выбросили, это явно не то чего всем хочется.


                  $items = array_map($row => $this->hydrator->hydrate($row), $rows);
                  $items = array_map($row ~> $this->hydrator->hydrate($row), $rows);
                  $items = array_map($row ==> $this->hydrator->hydrate($row), $rows);
                  $items = array_map(function ($row) => $this->hydrator->hydrate($row), $rows);
                  $items = array_map(function ($row) { return $this->hydrator->hydrate($row); }, $rows);
                  $items = array_map(function ($row) { 
                      return $this->hydrator->hydrate($row); 
                  }, $rows);


                  1. Fesor
                    14.06.2017 23:05

                    это явно не то чего всем хочется.

                    ну тут как говорится, "хоти в одну руку, а..." Увы приходится идти на компромиссы в пользу простоты сопровождения парсера и отсутствия нарушений обратной совместимости :(


                    1. LastDragon
                      14.06.2017 23:16

                      Имхо, добавлять кривой сахар смысла совсем нет, поэтому или действительно короткий синтаксис (лучше похожий на что есть в других языках) или ничего.


                      1. Fesor
                        14.06.2017 23:58

                        Представьте что вас просят добавить фичу, и вы можете реализовать фичу двумя способами:


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

                        Да, второй вариант всем не понраву, но он решает проблемы какого-то процента пользователей. Либо же не делать ничего. Как бы вы поступили?


                        1. Nahrimet
                          15.06.2017 00:21
                          +1

                          А Вы, как бы поступили?)

                          Лично на мой взгляд, в php достаточно фич из разряда makeSomethingLikeFooButInAnotherWay. Если можно удержаться от «двусмысленности», то лучше так и поступить.


                        1. LastDragon
                          15.06.2017 07:42

                          Выбрал бы первый вариант (==> отношу к нему же) — кривая фича вообще никому не нужна (их тут и так слишком много), если это что-то ломает — есть следующая мажорная версия, а если это слишком сложно — не стал бы делать.


                          1. Fesor
                            15.06.2017 11:21

                            Выбрал бы первый вариант

                            то есть "то что они хотят, но это усложнит реализацию на порядок и вам придется ее поддерживать годами (дорого)".


                            а если это слишком сложно — не стал бы делать.

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


                            Но все еще есть процент людей которым фича нужна даже с "лишним" кейвордом в начале.


                            То есть проблема — люди думают только о себе. Тем кто не видит смысла — фича не обязательная. С другой стороны убрать кейворд и сделать его опциональным в будущем не составляет особо проблемы.


                            1. LastDragon
                              15.06.2017 12:17

                              то есть

                              Да, однако вы упускаете что поддерживать надо всё, поэтому, в данном случае, нежелание сделать нормально сразу это обычная лень.


                              Но все еще есть процент людей которым фича нужна даже с "лишним" кейвордом в начале.

                              Она была нужна давным давно, сейчас смысла в ней не очень много на самом деле. Но вообще дело не в лишнем function, а в том что эта запись совсем не короткая, глядишь там еще и use придется писать, а то сложно же по другому сделать...


                              1. Fesor
                                15.06.2017 15:25

                                нежелание сделать нормально сразу это обычная лень.

                                вам надо сделать в парсере гиганский кастыль который сможет чекать на N лексем вперед. Я не считаю что это "сделать нормально".


                                сейчас смысла в ней не очень много на самом деле.

                                аргументируйте. Есть альтернативы?


                                глядишь там еще и use придется писать

                                Почитайте RFC. В частности:


                                importing used variables from the outer scope implicitly

                                а то сложно же по другому сделать...

                                это как раз таки сделать не сложно. Сложно с парсером без кейворда в начале выражения.


                                1. LastDragon
                                  15.06.2017 16:40

                                  аргументируйте. Есть альтернативы?

                                  Что именно аргументировать? Анонимные функции есть давным-давно, короткий синтаксис всего лишь сахар, который первый раз был предложен пару лет назад (там кстати даже pr был...), за это время все уже привыкли к стандартному синтаксису + явный use имеет свои преимущества.


                                  1. Fesor
                                    15.06.2017 19:58
                                    +1

                                    Есть большая разница между "анонимными функциями" и "функциональными выражениями". В JS мире эту разницу тоже не сильно понимают потому пихают arrow functions бездумно.


                                    явный use имеет свои преимущества.

                                    которые не имеют смысла в этом контексте.


                                    за это время все уже привыкли к стандартному синтаксису

                                    примерно так же про синтаксис массивов говорили.


                                    1. LastDragon
                                      15.06.2017 21:08

                                      Есть большая разница между "анонимными функциями" и "функциональными выражениями".

                                      И в чем же эта разница?


                                      примерно так же про синтаксис массивов говорили.

                                      А вот его как раз реализовали правильно :)