PHP-Дайджест № 118 – свежие новости, материалы и инструменты (24 сентября – 9 октября 2017)


    Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 RC 3 и другие релизы, 5 лет дайджесту, предложения из PHP Internals, свежая книга по асинхронному PHP, новое расширение-профайлер, и многое другое.
    Приятного чтения!



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



    PHP Internals


    • [RFC] Allow a trailing comma in function calls — Предлагается разрешить использовать запятую в конце списка аргументов функций:

      var_dump(
          $whatIsInThere,
          $probablyABugInThisOne,
          $oneMoreToCheck,
      );
      
    • Еще не вышел PHP 7.2, а уже идет полным ходом работа над следующими версиям. Например, в 7.3 реализована оптимизация sparse conditional constant propagation. Это позволяет интерпретатору упростить вот такую функцию:

      Class C {
          public $i;
      }
      
      function fn(int $x) {
          $c = new C;
          $c->i = 1;
          if ($x) {
              $a = [1, 2, 3];
          } else {
              $a = [3, 2, 1];
          }
          return $a[$c->i];
          $c->i++;
          return $x;
      }
      

      до вот такой:

      function fn(int $x) {
          return 2;
      }
      

      Ждем новостей о JIT, над которым также ведется работа.

    Инструменты


    • jenssegers/date — Библиотека на базе Carbon для работы с датами и поддержкой мультиязычности. Прислал denisyukphp.
    • json-api-php/json-api — Библиотека описывает бизнес-правила JSON API на языке доменной логики. Прислал f3ath.
    • codeception/codeception-progress-reporter — Прогресс-бар для Codeception. Прислал fr05t1k.
    • hybridauth/hybridauth — Одна из самых популярных библиотек для аутентификации с помощью соцсетей.
    • Bit-Wasp/bitcoin-php — Реализация протокола Bitcoin на PHP.
    • Webiny — Интересная CMS с бэкендом на PHP и ReactJS на фронтенде.
    • nbs-system/snuffleupagus — Расширение для PHP 7+, призванное повысить безопасность исключив на корню некоторые классы ошибок.
    • NoiseByNorthwest/php-spx — Простой, но весьма интересный профайлер в виде расширения. Может стать годной альтернативой XDebug и XHProf.

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



    Аудио и видеоматериалы


    • www.phppodcasts.com — Все англоязычные подкасты по PHP на одном сайте.

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



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

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


    Сегодня PHP-Дайджесту исполняется 5 лет! За это время было опубликовано 6203 ссылки. А вот так выглядел самый первый выпуск.
    Огромное спасибо всем, кто помогает делать дайджест, тем, кто присылает ссылки и правки, пишет статьи и разрабатывает инструменты, и, конечно же, огромное спасибо вам! Вместе мы делаем PHP-мир лучше!

    Zfort Group 329,84
    Компания
    Поделиться публикацией
    Комментарии 53
    • +9
      Спасибо за дайджест и вашу работу за все 5 лет :)
      • –5
        var_dump(
            $whatIsInThere,
            $probablyABugInThisOne,
            $oneMoreToCheck,
        );


        Вот не надо нам этого счастья
        • +4
          Отсутствие последней запятой приводит изменению двух строк в коде вместо одной строки при добавлении новой переменной в var_dump(). В результате, diff в коммите будет показывать две строки, то есть, в два раза больше, чем необходимо.
          • +2
            Разве это проблема? Зато сразу видно, что запятая не была забыта. А вот при чтении кода с этой «лишней» запятой как-то не сразу очевидно что происходит.

            public function foo($a, $b, $c = 3);
            


            foo(1, 2); // всё понятно
            foo(1, 2, ); // неочевидно, может быть теперь в c придёт null?
            


            Ещё и выглядит некрасиво.
            • +2

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

              • –6
                Мы в проекте наоборот, в массивах тоже запрещаем. Чтобы не было «недосказанности».
                • +9
                  Так и запрещайте на здоровье. У себя. А нам удобно и то и то.
                  • 0

                    А через PHP Coding Standards Fixer не прогоняете код?

                • +6
                  >Ещё и выглядит некрасиво.
                  Если в одной строке, то некрасиво. А вот если в разных строках, то как раз некрасиво без запятой.
                  • 0

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

                    • +1
                      Allowing a trailing comma in function calls will make it more convenient to append arguments in many contexts where it is common to call a function with lots of arguments; especially variadic functions.


                      «especially», но прям про ограничение я нигде не вижу.
                      • +2
                        Никогда не понимал зачем нужны функции с переменным количеством аргументов.
                        Лишний сахар как по мне.
                        В древности оно было уместно, когда не было короткой записи массивов и писать foo($arg1, array(1,2,3,4,5)) было явно некрасиво, но когда мы говорим о семерке, то foo($arg1, [1,2,3,4,5]) выглядит красивее чем foo($arg1, 1,2,3,4,5) просто в силу сохранения семантики. А уж делать foo([1,2,3,4,5]) так вообще проблем не вижу.
                        При этом скармливать таким функциям массивы — неудобно. желательно делать две версии функции. Реализация таких функций, если это не частный случай где все элементы равноправны (т.е. аналог foo([1,2,3,4,5])), то нужно их разделять и т.п.

                        Нет, я понимаю что оставлять их нужно, ведь это обратная совместимость, но развивать это направление ИМХО не стоит.
                        • +1
                          Поддерживаю, у меня схожие мысли.
                          Раньше были функции принимающие массив, когда заранее было не известно сколько элементов хочу передать, типа
                          $table->addColumns([$columnDescription1, $columnDescription2, $columnDescription3])


                          Затем я стал использовать функции с переменным числом параметров
                          $table->addColumns($columnDescription1, $columnDescription2, $columnDescription3)


                          Но при форматировании код вызывающий функцию с переменным числом параметров частенько оказывался многострочным (много параметров), а висячую запятую добавить после последнего нельзя. Когда хочешь добавить ещё один параметр в конец или передвинуть последний выше всё время приходится следить за последней запятой (которой не должно быть). + традиционная проблема с diff
                          
                          $table->addColumns(
                              $columnDescription1,
                              $columnDescription2,
                              $columnDescription3
                          );
                          

                          с массивами удобнее:
                          
                          $table->addColumns([
                              $columnDescription1,
                              $columnDescription2,
                              $columnDescription3,
                          ]);
                          

                          В этом плане я обоими руками за висячую запятую после последнего параметра при вызове.

                          Но есть другой момент. Практика показала, что эти параметры зачастую на столько динамичны, что их не удаётся выделить в отдельные переменные, они формируются на ходу, в зависимости от каких-то условий, например:
                          
                          $columns = [$columnDescription1, $columnDescription2];
                          if ($x) {
                              $columns[] = $columnDescription3;
                          }
                          $columns[] = $columnDescription4;
                          
                          // В итоге опять передаём массивом
                          $table->addColumns($columns);
                          


                          В итоге первоначальный энтузиазм по поводу функций с переменным числом параметров угас, а многое из того, что было написано в новом стиле скатилось обратно к массивам.
                          • 0
                            Если я не ошибаюсь с седьмой версии PHP можно сделать распаковку для вашего массива
                            $table->addColumns(...$columns);
                            • –1
                              можно. но… зачем?
                              Три символа которые пусть и просты, но не совсем очевидны (нужно знать синтаксис, прочитать что он значит, в других языках этого нет, в старых версиях не было, используется не часто и т.п.) для того чтобы… барабанная дробь… не писать два символа которые по синтаксису очевидны, внесены давно, и используются часто, т.е. даже новичек поймет что они значат.
                              Нет, можно и так. Но это несколько противоречит текущему тренду, где даже оформление кода стараются стандартизировать для простоты понимания и чтения.
                              Вместо того чтобы задепрекейтить 90% функционального синтаксиса (который имеет много исторически предопределенных корявостей и проблем с единообразием) в пользу его ООП-аналогов (которые пусть тоже не без греха, но почище) — так нет, пишем больше сахара для функций (и да, я понимаю что методы суть функции, но опять таки — ну вот зачем?
                              Делаем из пхп вторую java? Цена этому ведь не только зависимость от ИДЕ/документации (ведь всё заучить просто невозможно и в пхп подглядывать надо чаще чем в других языках) но и лишнее усложнение того что под капотом — и парсера, и внутреннего апи и самого интерпретатора.
                              RISC-архитектура показала что в простоте сила.
                              • 0
                                Не функционального, а процедурного синтаксиса.
                                • 0
                                  Вы правы, наименование (даже чужие термины) мое слабое место. Зато я редко ошибаюсь на единицу :)
                    • +5

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


                      Программирование безнадежно устарело тем, что воспринимает код как текст. Гит — это частность этой проблемы. Гит работает со строками, а не AST.

                      • 0
                        И программист устарел, поскольку мыслит в текстовом виде.
                        Читать деревья сложно. Коммит «как текст» прочитать просто. А вот коммит в граф — будет непонятным.
                        Я больше склоняюсь к варианту на подобии keyword-driving… Собственно даже не склоняюсь, уже второй год пилю фреймворк в таком ключе, надеюсь через месяц выкатить.
                        • 0

                          я не говорил ни про что из вышеперечисленного. Проблема не в том, что мы пишем текст. Проблема в том, что программы между собой общаются текстом.


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

                          • +2
                            Кирилл, дело в том что с текстом проще работать. Это универсальный формат. Тестовая строка и всё. Дифф тоже прост как тапок. А напишите дифф для xml, ну или просто для дерева. Да что там для дерева. Просто напишите логику для переноса куска кода из одного файла в другой. В тексте, не в виде дерева.
                            Гит вон отказался от операции переименования, оставив удаление-добавление.
                            У меня в проекте пхп, хтмл, лесс, жаваскрипт, шаблонизатор, жсон, хмл, баш и парочку своих форматов. Ну в общем как у всех… И все это гиту без проблем. Синтаксический анализ не нужен и т.п.
                            А это как вы говорите «вершина айсберга».
                            В те времена когда 640килобайт хватало на всех — бинарные форматы были максимально в ходу. Даже старый добрый бейсик у Спектрума (с которого многие тут начинали) хранился в своем особом байт-коде.
                            А сейчас даже мелкомягкие в офисных форматах взяли более «текстовыйе» внутренние форматы.
                            Текстовый формат тупо проще.
                            • 0

                              Дело в том, что с ассемблером проще работать. И далее по тексты.


                              "Проще" никак не отрицает устаривания. Почему-то присать на расте, который компилируется в js и далее по стеку — это класно и модно.
                              А понять, что текст устарел — это истерика и пена изо рта.


                              Вообще, я дальше не буду отвечать. Этот разговор уже был, когда юникс обсуждали.

                              • +1
                                Дело в том, что с ассемблером проще работать.

                                Проще чем с чем? Чем с машинными кодами? Конечно проще. Он ведь текстовый. Собственно для этого его и изобрели — текстовый, читаемый формат, относительно легко понять и машине и человеку, в отличии от машинных кодов. Покажите мне тех кто пишет в машинных кодах. Их нет. А на ассемблере пишут очень многие, там где мощности ограничены.
                                Нет, я понимаю что вы из молодого поколения не видевшего первокарты, и считаете что ассемблер это что-то совсем низкоуровневое, но нет, ассемблер это как раз текст а не бинарный формат.

                                «Проще» никак не отрицает устаривания.

                                По такой логике RISC-архитектура устарела еще до того как ее даже не разработали а только начали задумываться.

                                Реальность же немного отличается от того что вы себе придумали.
                                Не может технология устареть если ей еще не существует альтернативы.
                                Но даже когда (если) альтернатива появится устаревания вот так сразу не наступит. Технология должна не просто существовать, но и быть применима не в одном отдельном кейсе применения старой технологии, а в значительной его части. Но и этого недостаточно. Самое главное для того чтобы считать технологию устаревшей — альтернатива не просто должна справляться со значимой частью задач старой технологии, но и должна делать это эффективнее. Т.е. должна давать какое-то преимущество.
                                И в данном контексте у вас проблема.
                                Вы не можете просто взять и заменить одно частное применение. Например один язык. Нужно менять всю экосистему.
                                Ну вот взяли вы в своем языке за основу сохранять абстрактное дерево не в виде текста… а как? XML/JSON? Низя! Они ведь текстовые! ASN.1? Ничё так, нормальный формат. Избыточен, но мы ведь с закосом под то что «потом все будут как мы», так что архитектурный запас не помешает.
                                А дальше что? Пишем проект под нашим языком. Ой. Бинарный формат редактировать сложно. Даже готовые редакторы для ASN.1 категорически неприменимы для нашего частного случая. Так что своя собственная IDE.
                                Потом мы захотим чтобы у нас был контроль версий. Гит нам не подойдет, он такое не умеет. Вернее умеет, но оно будет нечитабельно (в смысле глазками читать дифы не получится). Так что делаем свой гит. Ну и попутно пишем аналогичные форматы для всего что есть в проекте. Шаблоны, таблицы стилей, конфиги, жаваскрипты… в общем всё что может встретиться в проекте, под все пишем свой синтаксис. У меня как-то был небольшой бекэндовый проект (т.е. без интефрейсов, шаблонов, и т.п.) в котором было использовано восемь языков программирования.

                                На практике все это окажется абсолютно неподъемно даже для крупных коллективов, и форель придется подрезать до «я не говорил что текстовый формат кода не нужно использовать вообще, я говорил что AST нужно использовать там где оно уместно», а потом внезапно окажется что оно и так используется там где уместно, а остальное — неуместно.
                                Использовать его почаще? Возможно. Но устаревшее… смешно.
                                • –1
                                  Нет, я понимаю что вы из молодого поколения не видевшего первокарты

                                  мухахаха
                                  эта ошибка стоит почти половину всего комментария.


                                  По такой логике RISC-архитектура устарела...

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

                                  • +1
                                    мухахаха
                                    эта ошибка стоит почти половину всего комментария.

                                    Вы знаете. В 1989-м, когда вам был годик а мне девять — я написал свою первую «игру». Это был бейсик на СМ-1800, и игрушка была простенькими вопросами-ответами.
                                    СМ-1800 это чудесная такая тумбочка с дисководом и ЭЛТ-монитором. Зеленым конечно. В то время черно-белые мониторы были роскошью.
                                    Тумбочка эта сделана на базе старого доброго к580, который суть клон интеловского 8080. Который еще надо было успеть скопировать, и всю экосистему развить. А в 91-м у меня уже дома был клон Спектрума, который помещался в клавиатуру и имел чуть больше мощности чем та тумба СМ. Перфокарты? Дед с ними дело конечно имел, и я даже их смутно помню не только в виде ящиков с макулатурой которую мы использовали для розжига на даче. Но самому? Да еще человеку моложе меня? Смешно, да.
                                    Даже не вижу смысла обьянять.
                                    Ваш опыт ничерта не стоит с такими ошибками.

                                    Может у меня и хреновый опыт, может его мало. Может я недостаточно умен. Но мой опыт мне подсказывает, что если я что-то знаю, и я высказал мнение отличное от мнения оппонента, то я об этом говорю конкретно. Прямо, с аргументами и т.п. Опыт подсказывает что люди неспособные аргументировать свою позицию как правило а) имеют ошибочное мнение б) прикрывают свою неспособность словами «ой всё» и «вы все равно не поймете, нет смысла объяснять».
                        • 0
                          ага, еще скажите писать HTML в виде DOM Tree
                          • 0

                            А вы все еще еще пишете HTML ?

                            • +1
                              Ага. Всё еще.
                              Если это не была шутка про HTML5 или про то, что тут правильнее сказать «пишем на HTML», то да, пишем.
                              Возьмем сферический пример. У меня есть проект, где фронта как такового нет. Это учетная система, которая по сути — допиленная под задачи админка.
                              У меня много разных полезных виджетов, больше дюжины разных видов полей у активФорм, виджеты вкладок, работы с файлами, таблицы, пагинации, фильтрации и поиска и т.п., есть куча типовых шаблонов на все случаи CRUD и еще немножко больше. В общем реально, на полсотни моделек и аналогичное количество контроллеров я не написал ни одного шаблона… (Ну ок, вру, написал, но это было уже после первого релиза, я допиливал шаблоны распечатки документов на цветном принтере чтобы влазило на us letter, но допустим мы бы остановились на первом релизе).
                              И что из этого? Я не писал на хтмл?
                              Простите, но нет. Все эти типовые шаблоны, все шаблоны для виджетов и т.п., они ведь не с Венеры прилетели, их кто-то писал. Если бы даже мне они достались готовыми и я бы их не писал, то кто-то ведь их писал…
                          • +1
                            Может тогда попробовать Лисп? У него синтаксиса нет, как говорят. Фактически сразу AST.
                      • +4
                        Поздравляю с пятилетием дайджеста! Не останавливайтесь — делаете полезное дело, спасибо за это!
                        • +1
                          Жаль, что hybridauth не поддерживает vk и mailru, при этом ok есть.
                        • +1
                          Для ленивых:

                          echo "\033[37;41mF\033[m";
                          выведет букву F на красном фоне
                          • 0
                            А как это работает?
                            • –4
                              Что именно как работает? Вам смысл этой шутки объяснить, или вы тоже, как комментатор ниже, статью не читали? Если вы пользовались PHPUnit'ом хоть раз, то, думаю, вам должно быть понятно и так.
                              • 0

                                Думаю вопрос был в том, почему тот код выведет то, что выведет. А не в чем шутка про тесты.

                                • +2
                                  Чё такой дерзкий?
                                  Я спрашивал — почему эхо выведет букву F.
                                • 0
                                  И?
                                  • –3
                                    Вы исходный пост читали? Если читали, то, думаю, вам не составит труда понять в чём шутка.
                                • 0
                                  del
                                  • 0
                                    function fn(int $x) {
                                    $c = new C;
                                    $c->i = 1;
                                    if ($x) {
                                    $a = [1, 2, 3];
                                    } else {
                                    $a = [3, 2, 1];
                                    }
                                    return $a[$c->i];
                                    $c->i++;
                                    return $x;
                                    }

                                    Это кусок же никогда не отработает
                                    $c->i++;
                                    return $x;
                                    • +1
                                      Так в том то и дело. Имеется ввиду, чтобы интерпретатор эту ахинею не выполнял — анализатор сразу схлопнет такой код до одной строчки, ибо структура кода позволяет.
                                      • 0

                                        А лучше бы варнинг выкинул) тогда можно было бы обратить внимание, вдруг опечатка или еще что)

                                        • 0
                                          Может я просто временно его поставил, а у меня процесс вылетать будет.
                                          Любой статический анализатор и нормальное IDE и так будет на это указывать.
                                        • +2
                                          Главное, чтобы грамотно сделали. Потому что i может быть магическим свойством, которое обрабатывается через __get и __set. В таком случае, при вызове $c->i++ может произойти все что угодно
                                          • 0
                                            при вызове $c->i++ может произойти все что угодно

                                            Именно этого вызова тут и не будет, но мысль да, верная, там вполне может быть
                                            Class C {
                                                private $fields;
                                                public function __get($name)
                                                {
                                                    $this->fields[$name]++;
                                                    return $this->fields[$name];
                                                }
                                                public function __set($name, $value)
                                                {
                                                    $this->fields[$name] = $value;
                                                }
                                            }
                                            • 0

                                              Вообще может быть и такое:


                                              class C {
                                                  public function __get($name)
                                                  {
                                                      if ($name === 'i') {
                                                          return 0;
                                                      }
                                                  }
                                                  public function __set($name, $value)
                                                  {
                                                      if ($name === 'i') {
                                                          file_put_contents('/file', $value);
                                                      }
                                                  }
                                              }

                                              Я не говорю, что так делать нужно или даже можно. Но гипотетически это реальная ситуация и интерпретатор должен учитывать и такие случаи. Таким же образом в конструкторе может происходить всякая мракобесия (создание lock файла, запись в БД и прочие вещи, которых там не должно быть). Поэтому вырезать лишний код нужно крайне аккуратно.

                                              • 0
                                                Ну дело в том, что пример из статьи это сферический пример, и вполне может оказаться что даже грамотный код ведет себя не так как задумано.
                                          • 0
                                            Интерпретатор это и так выполнять не будет.
                                            Единственно, если транслятор в байт-код вообще тупой, то он эти лишние две строчки оттранслирует.
                                            • 0

                                              Мб лучше бы уже тогда notice или warning кинул

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

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