Свежая подборка со ссылками на новости и материалы. В выпуске: 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-мир лучше!

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


  1. myrkoxx
    09.10.2017 08:36
    +9

    Спасибо за дайджест и вашу работу за все 5 лет :)


  1. SonicGD
    09.10.2017 09:56
    -5

    var_dump(
        $whatIsInThere,
        $probablyABugInThisOne,
        $oneMoreToCheck,
    );


    Вот не надо нам этого счастья


    1. lexxpavlov
      09.10.2017 10:05
      +4

      Отсутствие последней запятой приводит изменению двух строк в коде вместо одной строки при добавлении новой переменной в var_dump(). В результате, diff в коммите будет показывать две строки, то есть, в два раза больше, чем необходимо.


      1. SonicGD
        09.10.2017 10:16
        +2

        Разве это проблема? Зато сразу видно, что запятая не была забыта. А вот при чтении кода с этой «лишней» запятой как-то не сразу очевидно что происходит.

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


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


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


        1. Gemorroj
          09.10.2017 10:28
          +2

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


          1. SonicGD
            09.10.2017 10:29
            -6

            Мы в проекте наоборот, в массивах тоже запрещаем. Чтобы не было «недосказанности».


            1. roodz
              09.10.2017 10:56
              +9

              Так и запрещайте на здоровье. У себя. А нам удобно и то и то.


            1. mrsweet
              09.10.2017 11:18

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


        1. lexxpavlov
          09.10.2017 11:17
          +6

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


        1. ellrion
          09.10.2017 11:27

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


          1. SonicGD
            09.10.2017 11:36
            +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», но прям про ограничение я нигде не вижу.


          1. Mendel
            10.10.2017 10:08
            +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. PQR
              10.10.2017 11:22
              +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);
              


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


              1. disc
                10.10.2017 21:13

                Если я не ошибаюсь с седьмой версии PHP можно сделать распаковку для вашего массива

                $table->addColumns(...$columns);


                1. Mendel
                  10.10.2017 21:58
                  -1

                  можно. но… зачем?
                  Три символа которые пусть и просты, но не совсем очевидны (нужно знать синтаксис, прочитать что он значит, в других языках этого нет, в старых версиях не было, используется не часто и т.п.) для того чтобы… барабанная дробь… не писать два символа которые по синтаксису очевидны, внесены давно, и используются часто, т.е. даже новичек поймет что они значат.
                  Нет, можно и так. Но это несколько противоречит текущему тренду, где даже оформление кода стараются стандартизировать для простоты понимания и чтения.
                  Вместо того чтобы задепрекейтить 90% функционального синтаксиса (который имеет много исторически предопределенных корявостей и проблем с единообразием) в пользу его ООП-аналогов (которые пусть тоже не без греха, но почище) — так нет, пишем больше сахара для функций (и да, я понимаю что методы суть функции, но опять таки — ну вот зачем?
                  Делаем из пхп вторую java? Цена этому ведь не только зависимость от ИДЕ/документации (ведь всё заучить просто невозможно и в пхп подглядывать надо чаще чем в других языках) но и лишнее усложнение того что под капотом — и парсера, и внутреннего апи и самого интерпретатора.
                  RISC-архитектура показала что в простоте сила.


                  1. Corpsee
                    11.10.2017 07:10

                    Не функционального, а процедурного синтаксиса.


                    1. Mendel
                      11.10.2017 08:46

                      Вы правы, наименование (даже чужие термины) мое слабое место. Зато я редко ошибаюсь на единицу :)


      1. bm13kk
        09.10.2017 10:57
        +5

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


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


        1. Mendel
          10.10.2017 10:26

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


          1. bm13kk
            10.10.2017 14:57

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


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


            1. Mendel
              10.10.2017 15:38
              +2

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


              1. bm13kk
                12.10.2017 10:28

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


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


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


                1. Mendel
                  12.10.2017 13:47
                  +1

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

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

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

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

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

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


                  1. bm13kk
                    12.10.2017 14:26
                    -1

                    Нет, я понимаю что вы из молодого поколения не видевшего первокарты

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


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

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


                    1. Mendel
                      12.10.2017 15:53
                      +1

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

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

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


        1. Dmitri-D
          10.10.2017 12:29

          ага, еще скажите писать HTML в виде DOM Tree


          1. bm13kk
            10.10.2017 14:58

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


            1. Mendel
              10.10.2017 22:06
              +1

              Ага. Всё еще.
              Если это не была шутка про HTML5 или про то, что тут правильнее сказать «пишем на HTML», то да, пишем.
              Возьмем сферический пример. У меня есть проект, где фронта как такового нет. Это учетная система, которая по сути — допиленная под задачи админка.
              У меня много разных полезных виджетов, больше дюжины разных видов полей у активФорм, виджеты вкладок, работы с файлами, таблицы, пагинации, фильтрации и поиска и т.п., есть куча типовых шаблонов на все случаи CRUD и еще немножко больше. В общем реально, на полсотни моделек и аналогичное количество контроллеров я не написал ни одного шаблона… (Ну ок, вру, написал, но это было уже после первого релиза, я допиливал шаблоны распечатки документов на цветном принтере чтобы влазило на us letter, но допустим мы бы остановились на первом релизе).
              И что из этого? Я не писал на хтмл?
              Простите, но нет. Все эти типовые шаблоны, все шаблоны для виджетов и т.п., они ведь не с Венеры прилетели, их кто-то писал. Если бы даже мне они достались готовыми и я бы их не писал, то кто-то ведь их писал…


        1. JSmitty
          11.10.2017 09:58
          +1

          Может тогда попробовать Лисп? У него синтаксиса нет, как говорят. Фактически сразу AST.


  1. RonVisal
    09.10.2017 10:13
    +4

    Поздравляю с пятилетием дайджеста! Не останавливайтесь — делаете полезное дело, спасибо за это!


  1. polyanin
    09.10.2017 10:13
    +1

    Жаль, что hybridauth не поддерживает vk и mailru, при этом ok есть.


    1. lexxpavlov
      09.10.2017 11:20
      +1

      vk уже есть. Если так уж сильно нужен mailru, то можно и написать провайдер…


    1. zabidon
      09.10.2017 14:04

      Почему не поддерживает? тут есть в списке Additional Providers hybridauth.github.io/hybridauth/userguide.html#index


      1. polyanin
        09.10.2017 14:30

        Спасибо. А я вот тут hybridauth.github.io/providers.html смотрел только, видимо для 3 ещё не сделали.


  1. Sword_Dancer
    09.10.2017 14:04
    +1

    Для ленивых:

    echo "\033[37;41mF\033[m";
    выведет букву F на красном фоне


    1. ivvi
      09.10.2017 15:33

      А как это работает?


      1. Sword_Dancer
        09.10.2017 16:20
        -4

        Что именно как работает? Вам смысл этой шутки объяснить, или вы тоже, как комментатор ниже, статью не читали? Если вы пользовались PHPUnit'ом хоть раз, то, думаю, вам должно быть понятно и так.


        1. ellrion
          09.10.2017 16:26

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


        1. ivvi
          10.10.2017 13:34
          +2

          Чё такой дерзкий?
          Я спрашивал — почему эхо выведет букву F.



    1. iNickname
      09.10.2017 15:41

      И?


      1. Sword_Dancer
        09.10.2017 16:13
        -3

        Вы исходный пост читали? Если читали, то, думаю, вам не составит труда понять в чём шутка.


  1. iNickname
    09.10.2017 15:37

    del


  1. zlucan
    09.10.2017 18:27

    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. torf
      09.10.2017 19:14
      +1

      Так в том то и дело. Имеется ввиду, чтобы интерпретатор эту ахинею не выполнял — анализатор сразу схлопнет такой код до одной строчки, ибо структура кода позволяет.


      1. easty
        09.10.2017 20:01

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


        1. gro
          10.10.2017 12:32

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


      1. vtvz_ru
        09.10.2017 23:20
        +2

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


        1. Mendel
          10.10.2017 11:26

          при вызове $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;
              }
          }


          1. vtvz_ru
            11.10.2017 13:36

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


            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 файла, запись в БД и прочие вещи, которых там не должно быть). Поэтому вырезать лишний код нужно крайне аккуратно.


            1. Mendel
              11.10.2017 16:33

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


      1. gro
        10.10.2017 12:26

        Интерпретатор это и так выполнять не будет.
        Единственно, если транслятор в байт-код вообще тупой, то он эти лишние две строчки оттранслирует.


      1. alex6636
        10.10.2017 12:29

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