PHP-Дайджест № 183 (22 июня – 5 июля 2020)

    Фото James Titcumb

    Свежая подборка со ссылками на новости и материалы. В выпуске все про PHP 8: первая альфа, новое выражение match, баг в синтаксисе @@ для атрибутов, реальные бенчмарки JIT, 4 новых предложения. И, как всегда, инструменты, статьи, видео и подкасты.

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

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



    PHP Internals


    • check [RFC] Shorter Attribute Syntax — На голосовании по новому синтаксису для атрибутов победил вариант @@.

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

      Двусмысленность вот такая: function(@@X \ Y $z) может быть интерпретирован как function(@@X\Y $z) (атрибут X\Y и без типа) или function(@@X \Y $z) (атрибут X и \Y тип параметра). Потому что PHP допускает пробелы вокруг разделителя неймспесов.

      К счастью для поклонников синтаксиса @@, Никита нашел способ решить проблему, если будет принято предложение [RFC] Treat namespaced names as single token.
    • check [RFC] Match expression v2 — В PHP 8 будет доступно новое выражение match, которое работает по смыслу как switch, но при этом имеет проверку на тип и возможность возвращать значение.

      // Вот так работает switch:
      switch ('foo') {
          case 0:
            $result = "Oh no!\n";
            break;
          case 'foo':
            $result = "This is what I expected\n";
            break;
      }
      echo $result;
      //> Oh no!
      
      // То же самое на match:
      echo match ('foo') {
          0 => "Oh no!\n",
          'foo' => "This is what I expected\n",
      };
      //> This is what I expected
      
    • [RFC] Allow trailing comma in closure use lists — Предлагается разрешить опциональную запятую в конце списка use у замыканий по аналогии с тем, как уже сделано для аргументов и параметров функций.

      Скрытый текст
      $longArgs_longVars = function (
          $longArgument,
          $longerArgument,
          $muchLongerArgument,  // Здесь запятая в PHP 8.0 уже разрешена
      ) use (
          $longVar1,
          $longerVar2,
          $muchLongerVar3  // А вот здесь предлагается добавить
      ) {
         // body
      };
      
    • [RFC] Property write/set visibility — В этом документе предлагается сделать возможным указание двух модификаторов доступа для свойств: отдельно на чтение и запись. И есть два варианта синтаксиса:
      // Syntax Option A
      class User {
          public:private int $id;
          public:protected string $name;
      }
      
      // Syntax Option B
      class User {
          public private(set) int $id;
          public protected(set) string $name;
      }
      

      Судя по треду, что-то подобное будет, но уже в PHP 8.1, потому что требуется больше времени для обсуждения нюансов и пересечений с другими RFC, например, полноценными аксессорами, ридонли свойствами, иммутабельными классами.
    • [RFC] Language Constructs Syntax Changes — Поскольку declare и __halt_compiler — это не функции, а языковые конструкции, по типу как echo, то предлагается разрешить вызывать их без скобок.

      declare(strict_types=1);
      // =>
      declare strict_types = 1;
      
    • [RFC] Saner numeric strings — В этом RFC предлагается сделать два изменения по части обработки строк с числами.

      Во-первых, избавиться от концепции «строки, начинающейся с цифр». Например в таком случае echo '2str' + 2; результат будет не 4, а 2 и вместо E_NOTICE “A non well formed numeric value encountered” будет брошен E_WARNING “A non-numeric value encountered”.

      И во-вторых, разрешить пробельные символы в конце числовых строк, то есть чтоб "123 " == " 123" было true и все прочие операции работали, как и для строк с начальными пробелами.

    Инструменты


    • Guzzle 7 — Свежий релиз самого известного HTTP-клиента для PHP. Теперь клиент реализует стандарт PSR-18, минимальная версия PHP 7.2, добавлены тайпхинты.
    • deligoez/xDebug-Toggler — Приложение для macOS для быстрого включения/выключения Xdebug.
    • denisyukphp/tmpfile-manager — Менеджер временных файлов. Умеет закрывать ресурсы, автоматически или вручную очищать временные файлы, запускать свой сборщик мусора. Прислал @jebox.
    • php-aidc/label-printer — Библиотека для работы с принтерами этикеток с поддержкой языков Fingerprint, Direct Protocol, TSPL/TSPL2. Прислал jhaoda.

    Symfony



    Laravel



    Async PHP



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



    Аудио/Видео



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

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

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

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

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

      +5
      Ну что за дичь опять?

          public:private int $id;
          public:protected string $name;
      
          public private(set) int $id;
          public protected(set) string $name;

        0

        Что-то похожее есть в C#, но у него куда более элегантный вид:


        private string birthday;
        
        public string Name { get; set; }
        public string SecondName { get; }
        public string Birthday { 
            get; 
            set {
                birthday = String.Trim(value);
            }
        }

        Как по мне — изменения в целом стоящее, но не в этом вот виде, который предлагается.

          0

          Такой вариант как раз предлагался https://wiki.php.net/rfc/propertygetsetsyntax-v1.2, но не прошел голосование на тот момент.

            +1
            В питоне так

            class C:
                def __init__(self):
                    self._x = None
            
                def getx(self):
                    return self._x
            
                def setx(self, value):
                    self._x = value
            
                def delx(self):
                    del self._x
            
                x = property(getx, setx, delx, "I'm the 'x' property.")

            или декоратором

            class C:
                def __init__(self):
                    self._x = None
            
                @property
                def x(self):
                    """I'm the 'x' property."""
                    return self._x
            
                @x.setter
                def x(self, value):
                    self._x = value
            
                @x.deleter
                def x(self):
                    del self._x

            «private public» это что-то за гранью.
              +1

              Странно сравнивать с пайтоном, учитывая то, что в нем все свойства/методы публичные

                0
                Так и в php щас можно

                /** @property string x */
                class С
                {
                    public function __get($name)
                    {
                        return $name;
                    }
                    
                    public function __set($name, $value)
                    {
                        $this->x = $value;
                    }
                    
                    public function __unset($name)
                    {
                        unset($this->x);
                    }
                }
                
                  0

                  Это не совсем то. Каждое свойство отдельно не описывается

                    0
                    Можно ифы внутри магических методов написать. Но да, выглядеть это будет по уродски.
                +1

                А как в шарпе сделать протектед на чтение и приват на запись?

              0
              Тоже подгорает от такого. Сначала атрибуты абы как сделали, но ладно, на практике еще не использовали, но это за гранью уже. Чем им readonly properties не угодили? Тоже самое ж, читать читай, писать нельзя.
                0

                Ридонли возможно будут в виде атрибута https://wiki.php.net/rfc/readonly_and_immutable_properties (ранний черновик)

                  +3
                  Жаль что ссылаются на шарп, а делают через атрибуты.

                  почему не сделать так же?!
                  <?php
                  
                  class Person
                  {
                      public readonly string $name;
                  }
                  


                  Чтобы в конечном итоге иметь возможность работать в таком виде:
                  <?php
                  
                  class Person
                  {
                      public function __construct(
                          public readonly string $name,
                      ) {}
                  }
                  


                  И с классами так же
                  <?php
                  
                  readonly class Person
                  {
                      //
                  }
                  
                  

                +1
                А мне самая идея показалось толковой. Не придется делать какие-то левые свойства вроде $_id или геттеры/сеттеры, если ты хочешь менять свойство только внутри класса, но при этом сделать его public на чтение. В типичной entity таких полей будет большинство.
                  +1
                  Я за то, чтобы добавить гет/сет, это удобно, но синтаксис в таком виде — это ИМХО адъ.
                  +2
                  И во-вторых, разрешить пробельные символы в конце числовых строк, то есть чтоб «123 » == " 123" было true и все прочие операции работали, как и для строк с начальными пробелами.

                  Мне кажется это будет скорее вредное поведение, чем полезное. Лучше приучать разработчиков делать trim явно, где это требуется.
                    +3
                    Согласен. Скрытое поведение при работе с данными обожгло уже кучу народа, казалось бы, magic_quotes должны были кого-то чему-то научить. А вот это:

                    Например в таком случае echo '2str' + 2; результат будет не 4, а 2 и вместо E_NOTICE “A non well formed numeric value encountered” будет брошен E_WARNING “A non-numeric value encountered”.

                    … вполне может скрыто и очень плохо переломать чертову кучу вычислительного кода (включая финансы). Если уж делать такие изменения, то бросать E_ERROR, чтобы не было возможности втихую продолжить исполнение с неожиданным результатом операции. Само собой, это тоже слом совместимости, но хотя бы открытый.
                    +3
                    Спасибо за подборку
                      0
                      Синтаксис новых фич удручает.
                      Прям представляю как будет кипеть мозг когда массово начнут это использовать.

                      В том же Kotlin, C# всё на порядок очевидней, удобней и в целом не напрягает глаза.
                        +2

                        Вот Котлин:


                        var setterVisibility: String = "abc"
                            private set

                        Вот предложение для PHP:


                        private(set) string $setterVisibility = "abc";

                        ¯_(ツ)_/¯

                        0
                        match напоминает оператор из Rust, было бы очень удобно иметь подобную реализацию в PHP

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

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