PHP-Дайджест № 104 – интересные новости, материалы и инструменты (1 – 12 марта 2017)



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


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



    PHP


    • RFC — Deprecation of fallback to root scope — На данный момент в случае, если функция или константа не найдены в пространстве имен, будет попытка найти сущность с таким именем в глобальном пространстве. Предлагается объявить функциональность устаревшей и бросать ошибку уровня Notice:

      Undefined function \My\NS\strlen(), assumed \strlen()
      Undefined constant \My\NS\PHP_VERSION, assumed \PHP_VERSION
      

    Инструменты



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



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



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

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

    Прислать ссылку
    Быстрый поиск по всем дайджестам
    Предыдущий выпуск: PHP-Дайджест № 103
    Метки:
    Zfort Group 385,65
    Компания
    Поделиться публикацией
    Комментарии 33
    • +1
      Огромное спасибо за дайджесты и отдельное спасибо за наш stacker — не забыли, приятно.
      • 0
        antanas-arvasevicius/enumerable-type — Строго типизированная реализация Enum.

        Сколько себя помню :) всегда люди пытались реализовать Enum в PHP. Даже я пару раз пытался. Эта реализация выглядит лучше многих, но опять ограничения, прежде всего с десериализацией :( Что не так с PHP, что нельзя впилить такой тип в ядро?

        • 0

          Посмотрел код проекта. Оказалось все еще хуже чем я думал. Список доступных значений для ENUM получается с помощью рефлексии наследующего класса. Метод valueToString вообще мастерский говнокод.


          Я ENUM в PHP рассматриваю как ValueObject и отношусь к нему соответствующе. В сущностях храню сам объект, а не его значение, список доступных значений описываю в явном виде и добавляю методы необходимыми для бизнеслогики.

          • 0

            enum — ValueObject или значения типа enum — ValueObject?

            • 0

              не очень понял вопрос.


              Значение, для свойства объекта доменной области, может быть перечисление (enum). Для контроля за этим перечислением его удобно описать в виде объекта значения (ValueObject). Получается что-то вроде:


              $my_type = TicketType::priority();
              if ($ticket->type()->equals($my_type)) {
              }

              или так


              if ($ticket->type()->isPriority()) {
              }
              • 0

                Понял. Значения типа Enum — ValueObject.

            • 0

              все реализации ENUM в PHP через рефлексию. Так как у вас обычно классы ENUM условно маленькие а результат операции разумно кешируется во внутреннем поле, то накладные расходы весьма малы

              • 0

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


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

                • 0
                  Можно реализовать все тоже самое кеширование и прочие радости без рефлексии

                  это я не понял вообще


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

                  Это почему нельзя? что мне помешает?


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


                  Я вот пользуюсь реализацией myclabs/php-enum и там указываются константы.

                  • 0
                    Это почему нельзя? что мне помешает?

                    Пример на основе того же myclabs/php-enum. Я добавляю человеческое описание для вывода на frontend


                    class Action extends Enum
                    {
                        const VIEW = 'view';
                        const EDIT = 'edit';
                    
                        // константы воспринимаются как варианты значения
                        // формат предназначен для перевода
                        const TITLE_VIEW = 'acme.demo.action.view';
                        const TITLE_EDIT = 'acme.demo.action.edit';
                    
                        // можно использовать для radio/checkbox/select
                        public static function choices()
                        {
                            return [
                                self::VIEW => self::TITLE_VIEW,
                                self::EDIT => self::TITLE_EDIT,
                            ];
                        }
                    
                        public function title()
                        {
                            return static::choices()[$this->getValue()];
                            // можно былоб писать проще и не создавать метод choices,
                            // но тогда такую конструкцию тяжелее использовать для radio/checkbox/select
                            //return 'acme.demo.action.'.$this->getValue();
                        }
                    }

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


                    Пример на основе antanas-arvasevicius/enumerable-type. Я добавляю свои методы для бизнеслогики


                    class Action extends EnumerableType
                    {
                        final public static View()
                        {
                            return static::get('view');
                        }
                    
                        final public static Edit()
                        {
                            return static::get('edit');
                        }
                    
                        // воспринимается как вариант значения
                        final public static equals(Action $action)
                        {
                            return $this->id() === $action->id();
                        }
                    }
                    • 0

                      Чёт я запутался… вы пишете:


                      … случае использования подхода с рефлексией этого сделать нельзя.

                      я с этим не согласился и потом вы мне приводите именно пример что можно! Что то пошло не так?


                      в случая же 2 вы как то сразу схитрили. Зачем метод делать final public static? Да именно такие, и только такие, методы воспринимаются как значения. Ну ограничение той реализации. Точно так же как в myclabs/php-enum константы. Что особо не влияет на саму возможность делать


                      методы необходимые для бизнес логики и человеческое описание для вариантов значения для вывода на frontend.
                      • 0
                        я с этим не согласился и потом вы мне приводите именно пример что можно! Что то пошло не так?

                        Как раз я привожу пример что нельзя. myclabs/php-enum воспринимает константы с описанием как варианты значения. Тоесть метод Action::toArray() вернет TITLE_VIEW, что не корректно. Можно объявить TITLE_VIEW как не константу, но это все ухищрения чтоб угодить инструменту, а не бизнесу.


                        Хорошее решение этой проблемы предлагает библиотека marc-mabe/php-enum, которая воспринимает только публичные константы, но нужен PHP 7.1.


                        в случая же 2 вы как то сразу схитрили. Зачем метод делать final public static?

                        Да, схитрил. Естественно. Потому что с точки зрения бизнеса не должно быть final и не final методов. Весь объект должен быть final. А если инструмент требует помечать методы как final, то я вынужден и остальные методы тоже помечать как final, чтоб защитить класс.


                        Я хочу сказать, что используя подход с рефлексией, мы получаем автоматизацию генерации списка доступных значений (Action::choices()), и в тоже время некоторые ограничения на использование методов или констант.
                        Создав один метод Action::choices() вручную, мы сохраним все те же самые функции, но не будем иметь ограничений накладываемых рефлексией.

                        • 0

                          А… да по поводу непонимания мой косяк. Извиняюсь был невнимателен. День тяжелый.


                          Но всё же.


                          используя подход с рефлексией, мы получаем автоматизацию генерации списка доступных значений

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

                          • 0
                            И да, вы правы ограничения есть, однако это не это не равно утверждению "с рефлексией этого сделать нельзя".

                            Если ограничения не позволяют нам что-то сделать, значит это сделать нельзя. Разве нет?
                            Если ограничения накладываются в результате использования рефлексии, то значит "с рефлексией этого сделать нельзя".
                            Вроде все логично.


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

                            • +1

                              Попробовал реализацию через рефлексию. Оказалось действительно в чем-то удобнее. Спасибо что просветили.


                              Проблему с человеческим описанием в myclabs/php-enum можно решить так:


                              final class Action extends Enum
                              {
                                  const VIEW = 'view';
                                  const EDIT = 'edit';
                              
                                  // можно использовать для radio/checkbox/select
                                  public static function choices()
                                  {
                                      $choices = [];
                                      foreach (self::values() as $value) {
                                          $choices[$value->getValue()] = (string) $value;
                                      }
                              
                                      return $choices;
                                  }
                              
                                  public function __toString()
                                  {
                                      return 'acme.demo.action.'.strtolower($this->getKey());
                                  }
                              }

                              Но вот решил я сравнить производительность реализации через рефлексию и с явным описанием вариантов значений и получилось что рефлексия в 3-4 раза медленнее в зависимости от версии php.


                              $ php tests/benchmark.php 100000
                              Reflection enum: 1.25 MiB - 14079 ms
                              Reflection enum no magic: 1.25 MiB - 11286 ms
                              Explicit enum: 1.25 MiB - 3221 ms

                              Тест no magic это тест без использования магических функций __call() и __callStatic() и даже он оказывается медленнее в 3 раза.
                              Отсюда делаем вывод. За удобство нужно платить.

                              • 0

                                Хотелось бы взглянуть на бенчмарк полностью.

                                • 0

                                  Вангую что нет кэша для рефлексий.


                                  В целом же профит от enum-ов в возможности проверять по типам. Без этого смысла заморачиваться нет.

                    • 0

                      Я кинул пару PR в myclabs/php-enum, может вам пригодится

            • +2

              Отличная подборка в этот раз. Нашёл для себя новые штуки. Одно только огорчило:


              Двухфакторная аутентификация в Laravel с помощью SMS (Twilio)

              Не стоит рекламировать SMS в качестве фактора аутентификации. Дырявый канал.

            • +2
              https://wiki.php.net/rfc/fallback-to-root-scope-deprecation

              Самый странный RFC который я видел, это кому то реально нужно?
              • +1

                Как я понимаю, сильно упростит создание автозагрузчиков функций.

                • 0

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

              • 0

                -

                • 0

                  Автору Maxlab/stacker большое спасибо, недавно начал осваивать Docker, а тут все и сразу да еще и с виде о описанием.

                  • 0
                    На здоровье!) Ролики, только нужно переписать будет, на скорость делал, с первого раза — гомно конечно.
                  • +1

                    justinrainbow/json-schema не очень удобно использовать. thephpleague/json-guard как-то поприятнее.

                    • 0
                      Спасибо, добавил в подборку
                    • +3
                      Laravel Forge API — API сервиса теперь задокументировано. Имеется неофициальный клиент mpociot/blacksmith.

                      Пользуясь случаем попиарю свою реализацию API SDK — https://github.com/tzurbaev/laravel-forge-api :)

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

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