Новая версия PHP хоть и является минорной, но уже несёт множество новых, без преувеличения, крутых возможностей как для синтаксиса языка, так и для его производительности. Список новшеств не окончательный, но основные изменения уже внесены и приняты. Релиз планируется на декабрь 2019 года.
 

 
Ключевые изменения грядущей версии:

  • Типизированные свойства классов
  • Предзагрузка для улучшения производительности
  • Стрелочные функции для короткой записи анонимных функций
  • Присваивающий оператор объединения с null (??=)
  • Ковариантность/контравариантность в сигнатурах унаследованных методов
  • Интерфейс внешних функций, открывающий новые возможности для разработки расширений на PHP
  • Оператор распаковки в массивах

Подробнее об этих и других изменениях читайте под катом.

Disclaimer: Уже несколько раз в моих обсуждениях с коллегами фигурировала статья Брента «New in PHP 7.4». Сначала я хотел сделать перевод, но в процессе понял, что в тексте указаны не все последние обновления и присутствуют некоторые неточности, поэтому вместо перевода появилась эта статья.

Стрелочные функции (RFC)


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

array_map(function (User $user) {
    return $user->id;
}, $users)

array_map(fn(User $user) => $user->id, $users)

Некоторые особенности принятой реализации стрелочных функций:

  • Они могут получить доступ к parent области, таким образом, нет необходимости использовать ключевое слово use.
  • $this тоже доступна, как и в обычных анонимных функциях.
  • Стрелочные функции могут содержать только одну строку, которая также является оператором возврата значения.

Подробнее вы можете прочитать о них в этой статье на Хабре.

Типизированные свойства (RFC)

 
Ура! Свойства класса теперь смогут иметь type hint. Это очень долгожданное со времён PHP 7 изменение в направлении более строгой типизации языка. Теперь у нас есть все основные возможности для строгой типизации. Для типизации доступны все типы, за исключением  void и callable.

class Bar
{
    public string $name;
    public ?int $amount;
    public Foo $foo;
}

Если хотите чтобы я более подробно рассмотрел новые возможности типизации свойств объектов, отметьтесь в комментариях, и я напишу отдельную статью про них!

Присваивающий оператор объединения с null (RFC)


Вместо такой длинной записи:

$data['date'] = $data['date'] ?? new DateTime();

Теперь можно будет написать так:

$data['date'] ??= new DateTime();

Оператор распаковки в массивах (RFC)


Теперь можно использовать оператор распаковки в массивах:

$arrayA = [1, 2, 3];
$arrayB = [4, 5];
$result = [0, ...$arrayA, ...$arrayB, 6 ,7];
<i>// [0, 1, 2, 3, 4, 5, 6, 7]</i>

Обратите внимание, что это работает только с неассоциативными массивами.

Интерфейс внешних функций (RFC)


Интерфейс внешних функций (FFI) позволяет писать код на C непосредственно в PHP-коде. Это означает, что расширения PHP могут быть написаны на чистом PHP.

Следует отметить, что это сложная тема. Вам всё ещё нужно знание C, чтобы правильно использовать эти возможности.

Предзагрузка (RFC)


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

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

Повышение производительности происходит «небесплатно» — если предварительно загруженные файлы изменяются, сервер должен быть перезапущен.

Ковариантность/контравариантность в сигнатурах унаследованных методов (RFC)


В настоящее время PHP имеет в основном инвариантные типы параметров и инвариантные возвращаемые типы. Данное изменение позволяет изменять тип параметра на один из его супертипов. В свою очередь возвращаемый тип можно заменить на его подтип. Таким образом, данное изменение позволит более строго следовать принципу подстановки Барбары Лисков.

Пример использования ковариантного возвращаемого типа:

interface Factory {
    function make(): object;
}
class UserFactory implements Factory {
    function make(): User;
}

и контравариантного аргумента:

interface Concatable {
    function concat(Iterator $input);
}
class Collection implements Concatable {
    function concat(iterable $input) {/* . . . */}
}

Пользовательская сериализация объектов (RFC)


Становятся доступными два новых магических метода: __serialize и __unserialize. Данный механизм сериализации объединяет универсальность интерфейса Serializable с подходом реализации __sleep/__wakeup методов. Более подробно с их различиями можно ознакомиться в RFC.

Приоритет операций при конкатенации (RFC)


Если бы вы написали что-нибудь подобное:

echo "sum: " . $a + $b;

Сейчас PHP интерпретировал бы это как:

echo ("sum: " . $a) + $b;

PHP 8 будет интерпретировать это иначе:

echo "sum :" . ($a + $b);

PHP 7.4 добавляет предупреждение об устаревании при обнаружении выражения, содержащего "." перед "+ " или "-" и неокружённого при этом скобками.

Поддержка исключений в __toString (RFC)


Ранее исключения не могли быть выброшены из магического метода  __toString. Обоснованием этого поведения является то, что преобразования объектов к строкам выполняются во многих функциях стандартной библиотеки, и не все они готовы «правильно» обрабатывать исключения. В рамках этого RFC был выполнен всесторонний аудит строковых преобразований в кодовой базе, и данное ограничение теперь можно снять, что и было сделано.

Рефлексия для ссылок (RFC)


Библиотеки, такие как symfony/var-dumper, для точного вывода переменных сильно полагаются на ReflectionAPI. Раньше не было надлежащей поддержки рефлексии ссылок, что заставляло эти библиотеки полагаться на хаки для обнаружения ссылок. PHP 7.4 добавляет класс ReflectionReference, который решает эту проблему.

Добавлен метод mb_str_split (RFC)


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

Всегда доступное расширение ext-hash (RFC)


Это расширение теперь постоянно доступно во всех установках PHP.

PEAR не включен по умолчанию (EXTERNALS)


PEAR больше не поддерживается активно, core-команда решила удалить его из установки по умолчанию с PHP 7.4.

Реестр алгоритмов хэширования паролей (RFC)


Добавлена новая функция password_algos, которая возвращает список всех зарегистрированных алгоритмов хеширования паролей.

Слабые ссылки (RFC)


Слабые ссылки позволяют сохранить ссылку на объект, которая не препятствует уничтожению этого объекта. Например, они полезны для реализации кэш-подобных структур.

Разделитель числовых литералов (RFC)


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

1_000_000_000  // int
6.674_083e-11; // float
299_792_458;   // decimal
0xCAFE_F00D;   // hexadecimal
0b0101_1111;   // binary
0137_041;      // octal

Короткие открывающие теги объявлены устаревшими (RFC)


Короткий открывающий тег <? устарел и будет удалён в PHP 8. Короткий тег <?= (echo) не пострадал.

Левоассоциативный тернарный оператор объявлен устаревшим (RFC)


Тернарный оператор имеет некоторые странные причуды в PHP. Этот RFC объявляет устаревшими вложенные тернарные операторы.

1 ? 2 : 3 ? 4 : 5;   // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok

В PHP 8 такая запись приведёт к ошибке уровня компиляции.

Обратно несовместимые изменения (UPGRADING)


Вот некоторые из самых важных на данный момент обратно несовместимых изменений:

  • Вызов parent:: в классе не имеющем родителя объявлен устаревшим.
  • Вызов var_dump на экземпляре DateTime или DateTimeImmutable больше не делает доступными свойства объекта.
  • openssl_random_pseudo_bytes выдаст исключение в ошибочных ситуациях, вызванных библиотекой OpenSSL. Раньше она возвращала false, что могло привести к генерации пустой строки.
  • Попытка сериализировать PDO или экземпляр PDOStatement генерирует Exception вместо PDOException.
  • Вызов get_object_vars() на экземпляре ArrayObject возвратит свойства самого ArrayObject, а не значения обёрнутого массива. Чтобы как раньше получить значения обернутого массива — приведите ArrayObject к типу array.

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


  1. vav180480
    05.06.2019 11:16

    Насчет интерфейса внешних функций например на C я не понял этот код будет налету компилироваться всякий раз или только при первом запуске или еще как?


    1. eee
      05.06.2019 11:38
      +1

      Там вроде статически линкуются so-шки (dll-ки). Из сорцов нужны только хедеры, чтобы FFI знал сигнатуры методов и смог автоматом их забиндить. То бишь сишные либы должны быть компилированные под нужную архитектуру заранее.


    1. OlegXxl Автор
      05.06.2019 11:49
      +1

      Код заданный через FFI::cdef будет компилироваться условно каждый раз (но не забываем про оптимизации php). Так же есть возможность подгрузить код из C-header файла через FFI::load, но т.к. это занимает значительное время в RFC рекомендуется делать это 1 раз на старте приложения, а работу с FFI оформить через lazy load синглтон дающий доступ к FFI с заданным scope, при этом заранее скомпилировать opcache для него. Пример для второго подхода есть в секции RFC «A Complete PHP/FFI/preloading example».


      1. rjhdby
        05.06.2019 12:58
        +2

        Если раньше в ногу стреляли, то теперь подвезли гранаты. :D


    1. SerafimArts
      05.06.2019 15:01

      Насчет интерфейса внешних функций например на C я не понял этот код будет налету компилироваться всякий раз или только при первом запуске или еще как?

      Зависит от настроек в php.ini. По умолчанию FFI доступен только в файлах, которые загружаются с помощью preload функционала (файлы для которого, напоминаю, тоже указываются в ini конфигах).


      Пруфы:
      1) ffi https://github.com/php/php-src/blob/master/php.ini-production#L1892
      2) preload https://github.com/php/php-src/blob/master/php.ini-production#L1854


      UPD: Персональное ИМХО по этому всему: Функционал с прелоадом и ffi будет очень слабо востребован в связи с тем, что его почти невозможно нормально использовать.


      1. OlegXxl Автор
        05.06.2019 15:44
        +1

        Почему вы думаете что прелоад будет слабо востребован? Что касается FFI то это инструмент, как мне видится, скорее для разработки библиотек нового уровня, там где требуются большие\сложные математические операции и т.д., то есть для машинного обучения и прочего.


        1. SerafimArts
          05.06.2019 17:31

          Потому что он настраивается на уровне php.ini и как следствие — глобален на все проекты на сервере сразу (давайте временно забудем про докер и прочие штуки и возьмём в качестве примера типичный VPS прод или шаред).


          Так что либо придётся прописывать opcache.preload=/home/username/site.org/vendor/preload.php
          под один единственный проект. И при появлении site-2.org уже ничего с этим не сделать.


          Либо делать тоже самое на уровне fpm конфигов в виде php_flag[opcache.preload]=xxx. Что примерно тоже самое, но получше, т.к. можно отдельно воркеры под каждый ресурс запилить.


          1. OlegXxl Автор
            05.06.2019 23:13

            Ой как не хочется в текущем веку забывать про контейнеризацию. На VPS то ее кстати тоже вполне можно сделать. А про shared хостинги, придется извращаться, вы правы.


            1. SerafimArts
              05.06.2019 23:28
              +1

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


  1. Bartlab
    05.06.2019 11:58
    +1

    Отличный набор нововведений. Порадовал «Оператор распаковки в массивах»


  1. polyanin
    05.06.2019 13:23
    +3

    … писать код на C непосредственно в PHP-коде…
    а в C делать ассемблерные вставки!


    1. mapron
      05.06.2019 15:54

      Справедливости ради, там только декларации на С, что является довольно узким подмножеством языка)


  1. Sanovskiy
    05.06.2019 14:00

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

    <?php foreach($somedataarray as $key=>$var):?>
    Some HTML HERE
    <?endforeach?>
    

    Читается имхо хуже, чем <? foreach(): ?>


    1. mapron
      05.06.2019 16:00

      Дело привычки, мне сейчас кажется что эти 3 символа не решают.
      Да и тем более, foreach в шаблоне это не такая частая вещь, обычно это что-то вроде

      $view->renderPartial('element.template', $dataArray);  
      

      Для всяких списков, таблиц, и т.д.


      1. Sanovskiy
        06.06.2019 08:44

        Тут вполне прокатит <?=
        Я именно про циклы в шаблонах. Их довольно много обычно.


    1. tuxx
      05.06.2019 17:59

      Ох как битриксоиды будут рады


      1. koeshiro
        06.06.2019 00:08

        На Битриксе 7.2 это уже достижение и пара костылей с порога. Мне даже интересно что будет с php8


        1. vanxant
          06.06.2019 01:06

          А что за костыли если не секрет?


          1. Sanovskiy
            06.06.2019 09:01

            Да там велосипеды из костылей обычно


          1. koeshiro
            06.06.2019 09:03

            Mb и msqli подключаются отдельными загружаймыми пакетами.


            1. Sanovskiy
              07.06.2019 08:27

              В 2019 году кто-то все еще пользуется php_mysqli? О_о


              1. koeshiro
                07.06.2019 08:42

                Битрикс, как было сказано ранее.


              1. Fafhrd
                08.06.2019 15:11

                А в чем проблема с mysqli?


                1. Sanovskiy
                  08.06.2019 22:05

                  Морально устарел


  1. Zradko
    05.06.2019 15:45

    учу РНР с 5.3 версии. с каждой новой версией он развивается, улучшается
    <? объявили устаревшыми и исключения в __toString — порадовали.


  1. vanxant
    05.06.2019 16:56

    С изменением порядка операций будет адская веселуха. Зря они так.


    1. OlegXxl Автор
      05.06.2019 23:17
      +1

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


  1. EgDude
    05.06.2019 18:06

    Если хотите чтобы я более подробно рассмотрел новые возможности типизации свойств объектов, отметьтесь в комментариях, и я напишу отдельную статью про них!


    Отмечаюсь. Было бы интересно.


  1. Vitalicus
    06.06.2019 00:09
    +1

    Зачем удалить короткий "<?"?


    1. nsrwork
      06.06.2019 04:36

      Одна из причин это совпадение с синтаксисом xml, где то писали об этом...


      1. Sanovskiy
        06.06.2019 09:02

        Я не понимаю в чем проблема просто оставить его выключенным по умолчанию?


        1. SerafimArts
          06.06.2019 12:46

          Он и так сейчас выключен по умолчанию, уже больше пяти лет как. Но вы же видите ситуацию, выше в комментах люди даже не догадываются почему его удаляют, а на тостере полным-полно вопросов "почему гружу на продакшн и не работает".


  1. Compolomus
    06.06.2019 04:20

    Ковариантность/контравариантность
    Что то тут не понятно, можно чуть более расширить пример.
    Сначала думал там вместо типа сам объект указывается, но нет


    1. SerafimArts
      06.06.2019 12:47

      Реализация LSP для типов.


  1. Finesse
    06.06.2019 06:19

    Для типизации доступны все типы, за исключением void и callable.

    Грустно, что нельзя будет указать свойству тип callable. Я понимаю, что это сделано, чтобы решить такую неоднозначность:


    class Foo {
        public callable bar;
        public function bar() {}
        // ...
    }
    
    (new Foo)->bar(); // Вызовится свойство или метод?

    Но это не отменяет необходимость иногда хранить функции в свойствах объекта.


    Обратите внимание, что это работает только с неассоциативными массивами.

    Не верю. Функция array_merge и оператор + прекрасно работают с ассоциативными массивами. Почему тогда оператор распаковки не может?


    1. Sanovskiy
      06.06.2019 09:03

      Опишите логику поведения распаковки в случае коллизии ключей.
      Как на ваш взгляд оно должно работать?


      1. rjhdby
        06.06.2019 09:44
        +1

        Ну вот так себе аргумент между прочим

        Что выведет вот этот код?

        <?php
        $a=[1,2];
        $b=[2,...$a, 1=>3];
        var_dump($b);
        


        Внезапно
        array(3) {
          [0]=>
          int(2)
          [1]=>
          int(3)
          [2]=>
          int(2)
        }

        Смотреть upcoming releases, вывод для бранча php-master


        1. rsdc127
          06.06.2019 11:32
          +1

          А чему вы удивлены? Всё логично.
          Если по простому.
          1.

          $b = [2]; 
          #что эквивалентно 
          $b = [
            0 => 2
          ];
          

          2.
          $b[] = 1;
          $b[] = 2; 
          # что эквивалентно
          $b[1] = 1;
          $b[2] = 2;
          

          3.
          $b[1] = 3;
          


          Итог:
          array(3) {
            [0]=>
            int(2)
            [1]=>
            int(3)
            [2]=>
            int(2)
          }
          



          1. rjhdby
            06.06.2019 12:30

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


      1. Finesse
        06.06.2019 11:52

        Оператор может работать точно также как функция array_merge. В вашем примере будет выбрано то значение, которое стоит правее.


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


        function test(array $options) {
            $options = [
                'color' => 'red',
                'size' => 'big'
                ...$options
            ];
            return $options;
        }
        
        var_dump(test(['color' => 'green', 'mode' => 'demo']));
        /*
        [
            'color' => 'green',
            'size' => 'big',
            'mode' => 'demo'
        ]
        */


        1. HEKET313
          06.06.2019 21:22

          Обратите внимание, что это работает только с неассоциативными массивами.


          1. Finesse
            07.06.2019 03:32

            Я уже отвечал на это: #comment_20249626


            1. HEKET313
              07.06.2019 08:30

              Да, не внимательно прочитал, сорре. Мне тоже такая логика работы кажется странной


  1. Big_Shark
    06.06.2019 11:16

    Не очень что тут имееться ввиду, может кто обьяснить?


    Вызов var_dump на экземпляре DateTime или DateTimeImmutable больше не делает доступными свойства объекта.


    1. OlegXxl Автор
      06.06.2019 11:32

      Исправлен вот этот баг bugs.php.net/bug.php?id=49382.

      То есть теперь нет возможности сделать так:

      $dt=new DateTime('1742-05-23 00:00:00'); echo $dt->date;
      Notice: Undefined property: DateTime::$date
      
      $dt=new DateTime('1742-05-23 00:00:00'); var_dump($dt); echo $dt->date;
      DateTime Object ( [date] => 1742-05-23 00:00:00 [timezone_type] => 3 [timezone] => UTC ) 1742-05-23 00:00:00
      


  1. ghost404
    06.06.2019 11:48
    +1

    Сколько всего интересного))) И ковариантность/контравариантность это супер. Давно не хватало.


  1. inoyakaigor
    06.06.2019 17:03

    Это что же получается в стрелочной функции нельзя будет написать аналог вот этого JS кода?

    [1,2,3].map(item => {
        const newValue = '№' + item
        return newValue
    })
    


    1. SerafimArts
      06.06.2019 17:32

      array_map(fn($item) => '№' . $item, [1, 2, 3])


      1. porn
        06.06.2019 22:24

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


        1. inoyakaigor
          06.06.2019 23:26
          +1

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


          1. SerafimArts
            07.06.2019 00:48

            Печально, но видимо на то были причины

            Вот тут подробнее про эти самые причины: https://www.youtube.com/watch?v=teKnckg5x7I


  1. Athari
    08.06.2019 01:28

    Да они упоролись.


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


    Что идёт дальше — я не понял умора. Зачем-то выпилили <?, хотя это очень даже удобно. Не всегда и не везде нужна генерация XML, а если нужен XML, то недолго ровно в одном месте написать вывод через строчку. Для шаблонов удобно и красиво. Было.


    Менять приоритет операторов — это гениальный ход. Народ-то думал, что синтаксические косяки придётся тащить во имя обратной совместимости, но разрабы PHP были полны решимости. Забавно, что какой-то маргинальный синтаксис с конкатенацией изменили, а повсеместно нужный тернарный оператор запретили. Наверное, в этом есть какой-то скрытый смысл, но выглядит странно.


    Всё остальное выглядит положительно, в общем-то. На фоне предыдущих минорных обновлений вообще достойно.


    1. SerafimArts
      08.06.2019 04:41
      +1

      Что идёт дальше — я не понял умора. Зачем-то выпилили <?, хотя это очень даже удобно

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


      Для шаблонов удобно и красиво. Было.

      Для шаблонов есть шаблонизаторы.


      Менять приоритет операторов — это гениальный ход. Народ-то думал, что синтаксические косяки придётся тащить во имя обратной совместимости, но разрабы PHP были полны решимости.

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


      а повсеместно нужный тернарный оператор запретили

      Тоже самое что и выше: "Не читал, но осуждаю". Никто не запрещал тернарных операторов. Запретили говнокод в тернарниках.


      1. Athari
        08.06.2019 15:32

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

        <? не используется в публичных пакетах, потому что он непортируем. А вот в закрытых или личных проектах возможность писать шаблоны красиво — удобна. Чуваки из Битрикса, который каждый раз вспоминают при упоминании этого изменения, явно думали так же. Их код не нужно было запускать в условиях, когда <? недоступен.


        Проблема с XML высосана из пальца: если генератор XML гоняется через PHP, то строчкой <?="<?"?> решаются все проблемы. Да, похапэшным разрабам хочется убрать побольше царского наследия, когда поведение языка зависит от недоступных для изменения опций, и это похвально, но выкидывание <? — мёрвому припарка.


        Для шаблонов есть шаблонизаторы.

        Начерта мне шаблонизаторы, если похапэ сам по себе — отличный шаблонизатор? =) Я понимаю, что на большом сайте с десятками подключенных пакетов и активной поддержкой кода плюс-минус шаблонизатор — это статистическая погрешность, но не всегда хочется тащить в миниатюрный проект (а это ненулевая ниша) лишние внешние зависимости. Это не прихоть, это желание не тратить время ещё и на портирование на новую версию зависимости, когда интерпретатор (компилятор?) обновляешь.


        Тоже самое что и выше: "Не читал, но осуждаю". Никто не запрещал тернарных операторов. Запретили говнокод в тернарниках.

        Спасибо, я уже поржал с анализа ситуации в RFC: в 1000 топовых пакетов нашлось 12 использований тернарных цепочек, из которых 9 — баги, а 3 — вроде как норма. Эпик фейл с левой ассоциативностью тернарного оператора уже не исправить, поэтому запрет — это рациональное решение, но вообще-то поломка обратной совместимости в минорной версии в приличном обществе допустимой не считается (джависты вон дженерики поломали, лишь бы виртуальную машину не обновлять — учитесь, что называется =) ). Тем более, когда это ломает 12 из топовых 1000 пакетов, причём ломает не на уровне "в такой ситуации возникнет баг", а на уровне "вообще не запускается". Я уж молчу про менее популярные пакеты.


        С конкатенацией статистика заметно лучше (5 из 5 в топ 2000 — баги), но ссылка на RFC в статье поломана, и мне было лень искать нормальную, поэтому с первого захода не заценил.


        1. SerafimArts
          09.06.2019 02:12

          Начерта мне шаблонизаторы, если похапэ сам по себе — отличный шаблонизатор?

          Ну, скажем так, современные шаблонизаторы — это не только вывод с экранированием. И там нативному PHP до них как до луны.


          Но я допускаю, что возможно из-за того, что вообще не помню когда последний раз писал echo не совсем объективен в этом плане.


          поломка обратной совместимости в минорной версии

          Мы все прекрасно знаем какие у PHP "минорные версии"))) Такой же php 5.2 -> 5.3, например, вообще полностью изменил язык в своё время.


          джависты вон дженерики поломали

          Джависты себе давно язык сломали (пользуясь случаем) =)


          Тем более, когда это ломает 12 из топовых 1000 пакетов, причём ломает не на уровне "в такой ситуации возникнет баг", а на уровне "вообще не запускается"

          Ну вообще это ССЗБ. Смотря на такой код: https://github.com/symfony/messenger/blob/4.1/DependencyInjection/MessengerPass.php#L118 Мне рыдать хочется. Блин, неужели так сложно разрабам скобки расставить было? А ещё пишут что в симфони норм код...


          У меня нет, короче, контраргументов =) Ну убили совместимость, да, но как раз в тех местах за которые надо писателей на костёр отправлять.


  1. SerafimArts
    08.06.2019 04:41

    del (промахнулся веткой)


  1. Fafhrd
    08.06.2019 15:43

    Почему это 7.4 минорная версия?
    Команда давно отошла от классического semver
    7 — «версия» zend engine
    4 — мажорщина с крайне вероятной обратной несовместимостью
    остальное — фичи без нарушения обратной совместимости в пределах мажорщины, фиксы и прочая мелочь


  1. greabock
    08.06.2019 23:10

    Барбара Лисков довольно улыбается