Свежая подборка со ссылками на новости и материалы. В выпуске: обновления PHP, Laravel 5.8, Xdebug 2.7 и другие релизы, 3 свежих RFC, 2 принятых, и концепт из PHP Internals, порция полезных инструментов, и многое другое.

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



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



PHP Internals


  • [RFC] Saner string to number comparisons — В своем свежем RFC Никита Попов предлагает изменить поведение == и сделать нестрогие сравнения менее подверженными ошибкам. В частности, сравнение чисел предлагается использовать, только если сравниваемая строка на самом деле является числовой. В противном случае число преобразуется в строку, и выполняется сравнение строк.

    Данное предложение влечет за собой изменение поведения операторов сравнения  <=>==!=>>=<, и <=, конструкции switch, функций типа in_array(), sort() и других.

    В ответ поступили идеи разной степени радикальности: от введения специального флага declare('strict_comparison=1');, который бы превращал все == в ===, до предложения отменить == вообще.

    Ну а пока, в 7.4, вероятно, будет бросаться Warning, если результат сравнения отличается от предполагаемого в PHP 8.
  • [RFC] Permit trailing whitespace in numeric strings — Еще одно предложение призванное улучшить консистентность, но путем ослабления. Предлагается разрешить пробельные символы в конце числовых строк, то есть чтоб "123 " == " 123" и все прочие операции работали, как и для строк с начальными пробелами.
  • [RFC] Consistent type errors for internal functions — Предложение принято и значит в PHP 8 встроенные функции будут бросать TypeError в случае, если переданы параметры неверного типа и соответственно не будут при этом возвращать null.
  • [RFC] Weak References — Предложение по реализации слабых ссылок принято.
  • [RFC] Locked Classes — Предлагается ввести новое ключевое слово locked для классов. Такие классы будут закрыты для динамического использования свойств, то есть нельзя обращаться к необъявленным свойствам:
    Скрытый текст
    locked class TestClass {
        public $definedProp;
    }
    
    $t = new testClass();
    $t->definedProp = "OK";
    echo $t->definedProp;
    unset($t->definedProp);
    
    echo $t->nonExistentProp; // Error
    $t->nonExistentProp = "Not OK"; // Error
    unset($t->definedProp); // Error
    
  • video PHP Internals News: Episode 1 — Новый подкаст от автора Xdebug Derick Rethans. В первом выпуске разговор с Никитой Поповым.
  • Allow throwing from __toString()PR от Никиты с фиксом одной из старых проблем PHP – невозможность бросать исключения в __toString.
  • List comprehension — Концепт от Сары Гоулман с реализацией спискового включения (list comprehension) для PHP. Синтаксис менее элегантный, чем в Python, но выглядит интересно:
    $a = [1, 2, 3];
    $mul = 3;
    $c = [ for $a as $v yield $mul * $v use ($mul) ];
    

Инструменты



Symfony



Laravel



Yii


  • Yii 2.0.16.1
  • Релизный цикл Yii — Мажорный релиз поддерживается 5 лет, из которых 2 активных фиксов и 3 – фиксы ошибок безопасности.
  • zhuravljov/yii2-queue-monitor — Веб-интерфейс для мониторинга и управления очередями Yii2.

Async PHP



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



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

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

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

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

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


  1. xbs
    11.03.2019 18:10
    -1

    Продолжая тему wiki.php.net/rfc/string_to_number_comparison и неудачных примеров приведения типов в пхп, я выражаю свое согласие с вышеизложенными предложениями, они соответствуют моему виденью и нашли применения в моих ф-циях toInt(), toFloat().

    Я хотел бы обсудить аналогичную проблему каста в Boolean и String. Я столкнулся со следующими примерами, которые считаю неудачными и планирую переопределить в своих функциях кастования типа. В них я разграничиваю входные данные на ожидаемые и не ожидаемые для каждого из приведений типа.
    1) Случаи приведения типа в Boolean и моей ф-ции toBool().
    1.1) Стандартный каст (bool)5, (bool)-1 производят true. Я не считаю, что это правильно. Да, мы можем ожидать «1», «0», «1.0», «0.0», " 1 ", " 0 ", как репрезентацию true/false значений. Но если приходит 5 или -1 — это скорее говорит об ошибке переданных данных, чем об удачной возможности воспользоваться «магическим» преобразованием из коробки пхп.
    В моем случае toBool(5), toBool(-1) вернет Null значение, которое я возвращаю, в случае неудачной конвертации типа.
    1.2) (bool)«1.0», (bool)«1», (bool), " 1.0 ", производят true, как и ожидается.
    (bool)«0», производит false, как и ожидается.
    Но «0.0», " 0 ", так же производят true, что мне кажется неверным, моя toBool(«0.0») вернет false.
    1.3) (bool)«string» производит true, когда «string» не выглядит, как ожидаемое значение для булевого типа. В моем случае toBool(«string») возвращает null.
    1.4) (bool)"" производит false, что тоже по-моему мнению не верно.
    Похожий кейс обсуждается в статье для чисел, когда идет речь о сравнении (bool)(0 == ""), которое производит true, а предлагают сделать false.
    Я считаю, что toBool("") должно возвращать null, но здесь у меня сомнения.
    1.5) (bool)null производит false, когда я считаю, что должно производиться null. Мы ведь часто хотим иметь возможность сбрасывать булево значение в состоянии объекта, и присваивание null, как раз сбрасывает его. После, мы ориентируясь на факт, что значение сброшено (а не false), можем например загрузить значение по-умолчанию.
    1.6) (bool)[1], (bool)[0] — производит true, а (bool)[] — производит false.
    Я считаю, что массив — это не ожидаемое значение и не может быть преобразовано, значит надо вернуть null.

    2) Случаи приведения типа в String и моя ф-ция toString().
    В случае приведения типа в String, я вижу следующие сомнительные стандартные касты из коробки пхп:
    2.1) Если (string)true производит «1», тогда почему (string)false производит "", а не «0»?
    Я считаю, что true/false — булево значение не является ожидаемым значением для каста в стринг и в обоих случаях toString() должен вернуть null. Здесь меня терзают сомнения.
    2.2) (string)[] — производит E_NOTICE ошибку: «Array to string conversion», в моем случае toString([]) вернет null.

    3.1) Чтобы быть полным, хочу сказать, что я так же не считаю булевы значения, как ожидаемые для каста в числа, и toInt(true), toFloat(false) в моей парадигме произведут null
    3.2) Аналогично с массивом, toInt([1]), toFloat([]) производят null.

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


    1. BoShurik
      11.03.2019 18:45

      От to*() функций ожидаешь, что они любой треш преобразуют в соответствующий тип. Поэтому возвращение null мне кажется странным. Теряется смысл этих функций, потому что придется каждый раз дополнительно делать проверку на null. Тогда уж кидать TypeError, по аналогии с https://wiki.php.net/rfc/consistent_type_errors


      1. xbs
        11.03.2019 19:32

        В этих функциях есть второй параметр, который определяет применяемую фильтрацию, и всегда можно установить поведение по-умолчанию, как и усилить правила фильтрации, напр, вместо F_INT, использовать F_INT_POSITIVE, F_INT_POSITIVE_OR_ZERO.
        Эти функции не предназначены для валидации значений, а только для каста. Какие конкретно приведения в null вам кажутся странными? Почему toInt(null), toBool(null), toFloat(null), toString(null) производит null, я объяснил, мы хотим отличать неустановленное значение от 0, false, 0.0, "". Другие моменты, я тоже попытался обосновать.


    1. Mabusius
      11.03.2019 19:15

      «Работает — не трогай». Это ж какой лютый гемморой будет переходить на 8-ку, если это все сделают. Кучи явных и скрытых багов в логике повылезает просто ото всюду. А все изза того, что у когото перфекционизм головного мозга.


      1. xbs
        11.03.2019 19:27
        -1

        Т.е. вы считаете, что (bool)«0.0» === true — это корректно, когда (bool)«0» === false?
        Причем здесь перфекционизм? Инструмент должен работать однозначно и быть интуитивно понятным. Могу парировать, что у вас пхп головного мозга, раз вы бескомпромистно полагаетесь на правила кастинга, изобретенные специально для пхп и не повторяющиеся в других ЯП.
        И я не понял, какие проблемы меня ждут после перехода на пхп8? Пожалуйста, разъясните.


        1. vladqa
          11.03.2019 20:00
          +1

          Проблемы вас ждут из-за того, что в любом более-менее живом проекте ваш код — не единственный. Даже если допустить, что вы везде используете strict_types=1 и пишете исключительно корректный с точки зрения типов код, то ручаться за авторов всех библиотек, которые вы испольузете — невозможно.

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


          1. xbs
            11.03.2019 20:24
            -1

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


            1. vladqa
              11.03.2019 22:00
              +1

              При чем здесь вы и ваша библиотека. Речь идет о предлагаемых для 8 версии изменениях, в которых прямо указано:

              > This change to the semantics of non-strict comparisons is backwards incompatible. Worse, it constitutes a silent change in core language semantics. Code that worked one way in PHP 7.4 will work differently in PHP 8.0