Ниже приведены основные изменения, привнесенные PHP 7.1. Для получения полного списка утвержденных и обсуждаемых на текущий момент изменений проверьте официальный PHP RFC.

  • Перехват нескольких типов исключений за раз
  • Поддержка Curl HTTP/2 server push
  • Области видимости для констант классов
  • Возвращаемый тип void
  • Единое поведение строковых функций
  • Поддержка строковых параметров в функции list() и новый синтаксис c []
  • Выброс предупреждения при невалидных строках в арифметике
  • Объявление устаревшим mcrypt() и его последующее удаление

Перехват нескольких типов исключений за раз


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

try {
    // to do something
} catch (MyException $e) {
    // Handle this exception
} catch (AnotherException $e) {
    // Handle this in the same way as MyException
} catch (Exception $e) {
    // Handle this in a different way
}

В PHP 7.1, оба исключения, обрабатываемые в примере одинаково, можно поймать одновременно:

try {
    // to do something
} catch (MyException | AnotherException $e) {
    // Handle these exceptions
} catch (Exception $e) {
    // Handle this in a different way
}

Обратите внимание на синтаксис — это не обычный || оператор, который мы ассоциируем с or, это одинарный символ |.

Поддержка Curl HTTP/2 server push


Во-первых, что же такое server push? Лучшим способом, возможно, будет понять это через пример.

Как вы знаете, когда пользователь делает запрос к domain.com (не берем в расчет DNS и т.д.), веб-сервер отдает ответ с кучей разметки, которую браузер затем интерпретирует и отображает. В рамках этой интерпретации, исполняемой браузером, ему необходимо понять, какие дополнительные ресурсы он должен запросить, чтобы полностью отобразить страницу. Это включает в себя CSS, файлы JavaScript и изображения.

Server push стремится ускорить время загрузки и позволяет пропустить этот шаг, сразу направляя ресурсы клиенту напрямую.

Эта функциональность доступна в libcurl с версии 7.44.0, но пока нестабильна и не ушла в релиз (Подробнее: тут и тут). Для более подробной информации читайте официальный PHP RFC: ext/curl HTTP/2 Server Push Support.

Области видимости для констант классов


Константы классов в настоящее время нельзя сделать private или protected. Они всегда являются public.

Например:

class Panda
{
    private $pandaId;
    public $name;

    // This is public, and there's 
    // nothing you can do about it.
    const MAGIC_POWER = 20; 
}

PHP 7.1 вводит модификаторы видимости для констант:

class Panda
{
    // Constants default to public
    const MAGIC_POWER = 20;
 
    private const LIMIT_BREAK = 30;
    protected const EXPERIENCE_POINTS = 0;
    public const HEALTH_POINTS = 100;
 
}

Это ставит константы в один ряд с другими членами класса.

Возвращаемый тип void


Возвращаемые типы были добавлены в PHP 7.0. Напомню, что это позволяет разработчику явно объявить тип возвращаемого функцией значения.

Например:
function foo(): array {
    return [];
}

Начиная с PHP 7.1, можно указать, что функция имеет тип void, т.е. она выполняет действие, но ничего не возвращает.

function i_dont_return_anything(): void {
    // Perform some action
    // This is perfectly valid.
    return; 
    // This would throw a Fatal error (A 
    // void function must not return a 
    // value).
    // return true; 
}

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

Единое поведение строковых функций


Взгляните на встроеную в PHP функцию strrpos().

strrpos($needle, $haystack, $offset = 0); 

Последний параметр поддерживает отрицательное смещение, которое вместо того, чтобы найти последнее вхождение $needle в $haystack начиная от начала строки, находит последнее вхождение начиная с N позиций назад от конца $haystack.

Многие связанные со строками функции PHP имеют этот необязательный параметр $offset, а некоторые — нет. Один из ярких примеров — strpos(). Здесь, чтобы добиться отрицательного смещения, функцию необходимо объединить с substr(), что снижает читабельность и производительность кода.

Следующее обновление PHP устраняет данный пробел в языке, добавляя параметр $offset и его поведение с отрицательным значением во множество стандартных функций.

Поддержка строковых параметров в функции list() и новый синтаксис c []


В настоящее время в PHP есть возможность преобразовать массив в список переменных с помощью функции list():

Пример:

$myArray = ['monkey', 'tree', 'banana'];
list($monkey, $tree, $banana) = $myArray;
// $monkey is now equal to 'monkey'.

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

$myNamedArray = [
    'name' => 'Amo',
    'age' => 32,
    'location' => 'London'
];

PHP 7.1 решает это:

list('name' => $name, 'age' => $age, 'location' => $location) = $myNamedArray;

Другим значительным улучшением PHP 7.1. является введение квадратных скобок [] для обозначения массива переменных. Это обеспечивает альтернативу list() для разбиения массива на переменные.

[$a, $b, $c] = [1, 2, 3];

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

$numbers = [1, 2, 3];

Полная информация по этому изменению доступна на странице RFC.

Выброс предупреждения при невалидных строках в арифметике


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

Возьмем следующие примеры:

//Results in 10
$total = 5 + 5; 
// Results in 10
$total = '5' + '5';
// Results in 10
$total = 5+ '5';
// Results in 10
$total = '3 bananas yesterday' + '7 bananas today';
// Results in 5
$total = 5 + 'I love bananas';

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

Последний пример также демонстрирует подобное поведение в работе. В строке I love bananas нет числовых значений и вся строка трактуется как 0.

В PHP 7.1, примеры четыре и пять вернут:

Notice: A non well formed numeric string encountered in file.php on line x

Это вносит некоторые проблемы с обратной совместимостью в тех случаях, когда ожидается молчаливая обработка подобных строк. Можно заранее преобразовать заранее строки в целое число через (int) "string", но лично я думаю, если вы выполняете арифметические операции на подобных строках, то стоит задуматься о качестве этого кода.

Объявление устаревшим mcrypt() и его последующее удаление


Библиотека mcrypt была заброшена в 2007м году и содержит многочисленные ошибки и несмердженные патчи. Таким образом, вопрос ее включения в PHP давно уже созрел для рассмотрения.

В PHP 7.1 все mcrypt_* функции будут выдавать уведомление E_DEPRECATED. В PHP 7.1+1, они будут полностью удалены.

Помните, если вы используете mcrypt в вашем PHP коде, вы делаете это неправильно.

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

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


  1. impwx
    01.06.2016 16:24
    +6

    PHP 7.1 решает это:

    list('name', 'age', 'location') = $myNamedArray;
    

    А куда эти значения сохранятся? В переменные, названия которых совпадают со значениями этих строк?


    1. alexkunin
      01.06.2016 16:44
      +9

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

      list('name' => $name, 'age' => $age, 'location' => $location) = $myNamedArray;
      


      1. impwx
        01.06.2016 17:43

        О, так стало понятнее!
        Интересно, а выражение в качестве имени поддерживается, или только константные строки?

        $name = $random > 0.5 ? "a" : "b"
        list($name => $value) = ["a" => 1, "b" => 2];
        


        1. alexkunin
          01.06.2016 18:19
          +1

          По ссылке, которая есть внутри того документа, говорится, что можно. Смотрите тут: https://wiki.php.net/rfc/list_keys, раздел «Proposal». Более того, list() можно вкладывать в list() — там есть примеры, выглядят дико. А еще там чуть ниже есть интереснейший foreach вместе с list().


      1. webmoder
        01.06.2016 20:11
        -2

        ИМХО: статья не правильная была выбрана для перевода.

        > Note the syntax isn’t the usual double pipe || operator that we associate with or, rather a single pipe | character.

        > You might argue that every function should return something, if only a boolean to indicate successful execution, but that’s another discussion for another day.


      1. Fesor
        01.06.2016 23:37
        +1

        На самом деле крутата вот в чем:


        ['name' => $name, 'age' => $age] = ['name' => 'Sergey', 'age' => 24]; 
        echo $name; // Sergey
        echo $age; // 24

        называется это "деструктуризация", есть в куче языков и тд.


        1. rafuck
          02.06.2016 00:21

          Что-то я не увидел в спецификации, что будет, если запрашиваемый ключ в исходном массиве отсутствует: list('foo' => $bar) = array('bar' => 'foo');


        1. alexkunin
          02.06.2016 00:24
          +7

          Вот еще круче:

          $points = [
          ___[«x» => 1, «y» => 2],
          ___[«x» => 2, «y» => 1]
          ];

          foreach ($points as list(«x» => $x, «y» => $y)) {
          ___echo «Point at ($x, $y)», PHP_EOL;
          }


          1. Fesor
            02.06.2016 00:53

            Да, крутое применение деструктуризации


      1. servekon
        03.06.2016 00:57

        Не проще ли использовать

        extract($myNamedArray);
        

        ? Аж с 4-й версии можно.


        1. Fesor
          03.06.2016 01:07
          +1

          А теперь попробуем с другими ключами:


          ['lat' => $latitude, 'lng' => $longitude] = ['lat' => 39.465596, 'lng' => -86.858536];
          
          printf('My Coordinates: %.6f, %.6f', $latitude, $longitude); // My Coordinates: 39.465596, -86.858536

          Или еще интереснее:


          ['foo' => $bar] = ['foo' => 'hello', 'bar' => 'my', 'buz' => 'friend'];
          
          echo $bar; // hello
          echo $foo; // ошибка, нет такой переменной


  1. alexkunin
    01.06.2016 16:51
    +3

    Обратите внимание на синтаксис — это не обычный || оператор, который мы ассоциируем с or, это одинарный символ |.

    Это отлично пересекается предложением добавить Union Types, т.е. хинт может указывать на несколько типов. В IDE, кстати, такое давно можно указывать в аннотациях (как минимум в Шторме).


    1. bolk
      02.06.2016 08:46
      +1

      И «|» с «or» у меня он не ассоциируется, ассоциируется с бинарным «или», который тоже есть в PHP.


  1. denis-n-ko
    01.06.2016 20:10
    +3

    Спасибо за обзор!
    Еще nullable types (https://wiki.php.net/rfc/nullable_types) добавили, которого многие ждали


    1. Fesor
      01.06.2016 23:40
      +2

      а как же https://wiki.php.net/rfc/typed-properties? хотя его еще не в мерджили конечно, но это то чего я лично ждал уже пару лет.


  1. TheDoctor
    01.06.2016 20:10
    +4

    Сложилось впечатление, что началось движение в сторону более строгой типизации.
    «Возвращаемый тип void»
    «Выброс предупреждения при невалидных строках в арифметике»
    Возможно, это поможет избежать некоторые неоднозначности связанные с автоматическим преобразованием типов.


    1. impwx
      02.06.2016 11:09
      +1

      PHP — идеальный пример социокультурной инверсии в программировании. Сначала придумали одно, а потом началась бесконечная гонка за модными тенденциями из всех остальных языков программирования:

      • Изначально — структурный язык, со второй попытки добавили ООП, потом лямбда-функции, где необходимо явно указывать замыкания
      • Изначально — динамическая нестрогая типизация, потом четыре раза робко добавляли неполноценные ограничения, и это не считая изменений в 7.1
      • Изначально — язык, встраемый в шаблон. Потом сделали опциональным закрывающий тег, а теперь и открывающий предлагают убрать.
      • Опции register_globals и magic_quotes_gpc — сначала использовались во всех туториалах и самоучителях, потом объявлены опасными и удалены

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


      1. lexxpavlov
        02.06.2016 11:47
        +4

        >Но с таким багажом неудачных дизайн-решений и легаси светлого будущего можно ждать бесконечно.
        Это были не неудачные решения, это был маленький язык, который и был нужен сообществу. Если бы в 90х php изначально был бы как php7 сейчас, то вряд ли кто-то он был бы нужен — его бы никто не понял. Но теперь язык развился, сообщество развилось. Когда-то register_globals и magic_quotes_gpc были нужны, а сейчас — язык стал взрослее. Это нормально.


        1. Fesor
          02.06.2016 19:59
          +2

          Когда-то register_globals и magic_quotes_gpc были нужны

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


      1. alsii
        08.06.2016 14:40

        Это вы еще эволюции китообразных не видели ;-)


  1. Athari
    01.06.2016 20:20

    На lambda functions a.k.a. arrow functions, я так понимаю, забили?


    Печалька.


    1. Fesor
      01.06.2016 23:38

      там большой холивар на пустом месте родился… так что решили для 7.1 не делать. Может в 7.2...


      Есть реализация одного из предложений в yay (препроцессор для PHP) но мне не нравится...


  1. LionAlex
    01.06.2016 23:37
    +3

    // Results in 10
    $total = 'I ate 3 bananas yesterday' + 'and I ate 7 bananas today';
    

    Это неправда. Тут будет предсказуемый 0.

    А вот
    $total = '3 bananas yesterday' + '7 bananas today';
    

    вернет 10.


    1. NFL
      02.06.2016 00:43
      -2

      Голосовать не могу, но именно так. +1


    1. iGusev
      02.06.2016 00:46

      Спасибо, верно подмечено


    1. impwx
      02.06.2016 16:07
      +2

      $total = '3 bananas yesterday' + '7 bananas today';
      

      <sarcasm>
      Ожидаемый результат — строка "10 bananas tomorrow"!
      </sarcasm>


  1. POPSuL
    02.06.2016 00:54
    +1

    [$a, $b, $c] = [1, 2, 3];


    Господи! Я десять лет этого ждал!


    1. FlameStorm
      08.06.2016 02:55

      Заранее прошу не кидаться помидорами, — но стоит ли таких оваций этот кусочек синтаксического сахара
      относительно list($a, $b, $c) = array(1, 2, 3) ещё седого PHP 4,
      или относительно list($a, $b, $c) = [1, 2, 3] PHP 5.4+?

      Я бы так возликовал, если б в PHP реализовали вроде такой штуки:

      public function foobar($a, $b)
      {
      	__int64 $result;
      	__asm {
      		MOV EAX, $a
      		ADD EAX, $b
      		MOV $result, EAX
      	}
      	$result = parent::after_foobar($result);
      	$log->write("foobar called with result $result");
      	return $result;
      }
      


      1. Fesor
        08.06.2016 03:32
        +2

        Я бы так возликовал, если б в PHP реализовали вроде такой штуки:


        Ассемблерные вставки в динамическом языке программирования?) Нет уж спасибо.


        1. FlameStorm
          08.06.2016 12:42
          +1

          Ну а почему нет? Раз уж такая пьянка пошла, что void появился, да и в статье доходчиво описывается, как замечательно эволюционирует PHP. И то, что это интерпретируемый язык (ну почти, скорее псевдо-некомпилируемый), ещё далеко не исключает ассемблерные вставки.

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

          Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки, никакой фантастики в такой смеси. Это имело место быть потому, что многого «продвинутого» интерпретатор сам не умел, не мог предоставить любопытствующему программеру — взять CPUID, перейти в режим VESA аж 800х600 и 256 цветов, читать порты и т.д.

          Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.? Без необходимости привлечения для написания кастомного php-экстеншна, который потом до кучи придётся поддерживать?


          1. Fedot
            08.06.2016 13:14
            +1

            А разве ассемблерные вставки поддерживать легче чем расширение на C?


            1. FlameStorm
              08.06.2016 14:03

              Зачем их потребуется поддерживать и как-то изменять в коде, скажем, некой PHP-функции, если начиная с PHP X.X и выше всё это однозначным образом поддерживается из коробки? Один раз написал и оставь в покое.

              В варианте с Си, кроме того, что это другой язык а также требуются дополнительные стыковочные компетенции написания расширений, нужно не только тот же кусок асма написать (не скрою, что на Си это делать роднее и приятнее), но и попадаешь в зависимость от этой самой «стыковки». Написал расширение для 7.0, работает. Но возьми сменись в 7.3 несовместимо что-то в работе расширений — лишний головняк, вообще с асмом и твоим алгоритмом не связанный.


              1. Fesor
                08.06.2016 15:44
                +1

                кроме того, что это другой язык


                А ассемблер не другой язык?
                вообще с асмом и твоим алгоритмом не связанный.


                сменил процессор с x86-64 на arm и появился свой головняк.


                1. FlameStorm
                  08.06.2016 21:08

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

                  Однако сервер с нужным железом из облака (или collocation) можно просто выбрать такой, какой тебе нужен. Как правило (уже много лет как, сейчас и в обозримом будущем) это окажется тот или иной Intel Xeon. Впрочем, можно AMD-шный взять — по части устоявшихся технологий со стажем они предоставляют единообразный набор команд. Да, x86-64 для очень многих целей достаточно.

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


                  1. Fesor
                    08.06.2016 21:26
                    +1

                    Вообще-то нынче все в облаке и вы не знаете на каком железе крутится ваше ПО. Все за несколькими слоями абстракций. И это хорошо.


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


                    В целом же intel для этих ребят уже предоставляет возможность мувнуть алгоритмы на уровень железа за счет использования FPGA что намного круче ассемблерных вставок.


                    1. FlameStorm
                      08.06.2016 21:57

                      В облаке можно быть по разному, в том числе и заведомо выбирая тип и даже частоту проца. К тому же всегда можно выбрать вариант физически выделенного сервера / кластера, где ты точно знаешь свои ресурсы.
                      Алготрейдинг — читал про это, но не занимался, пока, такими вещами.

                      У всего свои плюсы и минусы, бесспорно.
                      Лично меня очень печалит тот факт, что за несколькими слоями абстракций, зависимостей разного степени качества, за обложенными подушками, костылями и железными конями современными разработчиками конечное железо производит полезную работу на уровне 1%, если не меньше, от того, что могло выдать в случае олдскул-гик подхода.

                      FPGA кстати, и вообще идея программирования в железе, действительно очень интересное направление.


                      1. Fesor
                        08.06.2016 22:17
                        +1

                        Так, давайте вернемся с небес на землю. Мы говорим про PHP:


                        • умирающая модель выполнения.
                        • блокирующее API, то есть 100% утилизация CPU уже не светит.
                        • сборка мусора, машралинг.

                        Итого, мы не получаем ровным счетом никакого профита от возможностей писать на ассемблере. Намного проще нужный функционал написать на Си или еще лучше на Rust и использовать в крайнем случае в качестве расширения PHP. В Node.js есть целые готовые библиотеки для rust что бы упростить этот процесс. Для PHP в целом тоже не так все сложно.


                        Как результат стоимость поддержки таких решений будет на порядок ниже и у нас будет четкое разделение ответственности. Тестировать такие вещи так же намного проще.


                        1. FlameStorm
                          08.06.2016 22:56
                          +1

                          Давайте, на землю можно. Главное не проскочить под землю в ад. )

                          Боюсь спросить о профите синтаксического сахара [$a, $b, $c] = [1, 2, 3] перед list, ну да не суть.

                          Да, модель выполнения с постоянной инициализацией-деинициализацией огромного слоя выполняемого кода в PHP на каждый запрос я тоже считаю злом, — тем, чего не должно быть в работе приложения-сервиса на сервере. И прочие минусы PHP сто раз подмечены.
                          Но всё же, статья о будущем, о PHP 7.1 и дальнейших планах. Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.

                          И в общем случае, вы неправы насчёт отсутствия профита. Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.

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

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

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


                          1. Fesor
                            09.06.2016 00:50
                            +1

                            Боюсь спросить о профите синтаксического сахара


                            Не бойтесь) Честно — это просто причесывание синтаксиса ради единообразия. Что бы синтаксис PHP больше походил на другие языки. Да, чуть потеряем самобытность, но все же это приятнее читается. И да, это мелочи.
                            Тут комментарии в стиле «давайте уже закопаем и пойдём на ноду», или вроде того, имхо, не очень к месту, хотя понимаю.


                            Я где-то к этому призывал? Если бы я так думал я бы уже давно писал на каком Go но нет, я все еще топчусь с PHP. Что до умирающей модели, есть уже кучи проектов вроде того же php-pm дабы невилировать эти издержки. Да и с асинхронщикой в PHP не все так плохо.
                            Если у нас есть критическое место, которое в обычной реализации ест более 80%-90% всего времени обработки запроса PHP, а после оптимизации через продвинутые x86-64 инструкции станет занимать менее 10% времени, то резон может иметь место.


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


                            На самом деле отсекающая причина простая. Вы сейчас можете это сделать без этой фичи? Можете. Это нужно 90% пользователей PHP? Нет. Это стоит того что бы инвестировать в это время вместо того что бы LLVM к opcache прикрутить или илнайнинг? Нет. И главное! Это дает разработчику возможность стрелять из гаубицы по своим ногам? Еще как.

                            Ну то есть это та же причина по которой в PHP нет из коробки потоков. Просто потому что в контексте WEB они ооочень редко нужны. И даже если брать экстенешн pthreads он сильно нас ограничивает в том как мы можем себя покалечить (в частности нет возможности шарить переменные между потоками неявно хоть оно все в одном адресном пространстве и крутится). Чем больше возможностей отстрелить ногу — тем больше их отстрелят.
                            А за дискуссию спасибо.


                            Вам так же!)


          1. Fesor
            08.06.2016 13:20
            +1

            Раз уж такая пьянка пошла, что void появился


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


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


            Еще как исключает. В этом просто нет смысла.
            Никто не заставляет использовать эту возможность, конечно.


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


            А зачем? Я вот могу написать все нужные алгоритмы на C/Rust и просто использовать это добро в PHP в качестве доп модуля. В итоге я получаю и векторизацию вычислений, и все что захочу. И при этом портируемость, стоимость поддержки будет явно ниже чем в случае ассемблерных вставок, ну и т.д.
            Помнится, даже реально чисто интерпретируемый Qbasic в 199х году поддерживал асмовые вставки


            А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.
            Так почему не дать самому PHP возможности для разработчика писать непосредственно в рамках языка эффективно по производительности некоторые алгоритмы, например, на SSE/SSE2, с использованием команд типа PUNPCKHQDQ, PMULUDQ и т.д.?


            Повторюсь, потому что рано или поздно это за нас будет делать интерпритатор. Сам будет запаковывать данные в вектора, сам будет заниматься векторизацией и т.д. К сожалению пока этому препятствует динамическая система тиепов. Даже в javascript векторизацию можно делать только в рамках simd API. Да даже в java с этим не так хорошо потому что есть такая штука как боксинг.

            А сейчас поскольку PHP не умеет так, вы можете это делать на каком rust и использовать его в PHP.


            1. FlameStorm
              08.06.2016 14:55

              Немножко занудного определения:

              Интерпрета?ция — пооператорный (покомандный, построчный) анализ, обработка и тут же выполнение исходной программы или запроса (в отличие от компиляции, при которой программа транслируется без её выполнения)


              Извините уж, и это давно не тайна, но современный PHP лишь условно интерпретатор. На самом деле он компилятор.
              Да. А именно:
              PHP читает PHP файл, транслирует, компилирует в opcode, и выполняет скомпилированное.

              Керосину в эту нашу библиотеку может плеснуть разве что eval, который is evil и который рекомендуется избегать по очевидной его мешаемости для статического анализа, трансляции и компилировании в опкод «интерпретатором» PHP.

              В частности, этап сгенерённых опкодов можно кэшировать всякими Zend Opcode+ / php-apc и т.д., что позволяет PHP пропускать этап трансляции и сразу приступать к выполнению ранее скомпилированной опкодной версии сурса.

              Еще как исключает. В этом просто нет смысла.

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

              А сегодня у нас 2016-ый год, LLVM, умные компиляторы, оптимизирующие компиляторы… Они зачастую выдают код намного более оптимизированный нежели может написать большинство людей. В 9x еще небыло так хорошо потому еще находились извращенцы которым это было нужно. Сегодня — это пережиток прошлого.

              О да. Теперь программированием, разработкой, сеньёр-девелопментом и т.п. занимаются, наконец-то, не какие-то там извращенцы, а настоящие профессионалы.

              Вообще, глядя на современные тенденции, можно скоро не удивляться заявлениям, что «The Hello World», не требующий
              — установки менее трёх сервисных сред,
              — от двадцати пяти зависимостей,
              — обязательное и широкополосное подключение к интернету для отправки персональных данных в корпорацию добра для заботы о вас,
              — а также не менее чем четырёхядерный проц
              — и полтара гигабайта доступной под этот «The Hello World» оперативки
              — e.t.c
              так вообще шляпа и пережиток каменного века. )

              Верю, будущее индустрии будет иным.


            1. POPSuL
              09.06.2016 00:56
              +1

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


              1. Fesor
                09.06.2016 01:36
                +1

                Не должны а желательно что бы они ничего не возвращали.


                Давайте для начала заменим термины: вызов метода — сообщения между объектами.


                Сообщения могут быть трех типов:


                • Запросы — сферический примером могут служить геттеры. Они возвращают нам значения но никогда не мутируют состояние. Только чтение.
                • Команды — опять же сферический пример — сеттеры. Они не возвращают значений а только меняют состояние.
                • Смешанные — классический пример — pop для стэка. Он одновременно возвращает вершину стэка и одновременно изменяет состояние стэка. Этот тип сообщений приходится использовать что бы добиться атомарности.

                Собственно из этого мы можем сделать вывод. Если у нас нет необходимости делать атомарно чтение + запись (а на самом деле это крайне редкий кейс) то лучше разделить ответственность на чтение и запись на два отдельных метода. Сделав это мы получаем возможность по разному комбинировать это добро и нам становится намного проще тестировать поведение объектов.


                1. POPSuL
                  09.06.2016 06:50

                  Ну вот на счет сеттеров я не совсем согласен.
                  Я вот предпочитаю цепочки вызовов, и часто пишу что-то вроде:


                  $object = (new SomeClass())
                      ->setSomething1($a)
                      ->setSomething2($b)
                      ->setSomething3($c);

                  И получается что это сеттеры, которые меняют состояние объекта, и возвращают ссылку на этот же самый объект.


                  1. Fesor
                    09.06.2016 10:54
                    +1

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


                    p.s. я так не делаю обычно, просто потому что редко пишу сеттеры.


      1. alsii
        08.06.2016 16:37
        +3

        Мне кажется, что если прикладном коде на PHP потребовались вставки на ассемблере, что явно "что-то пошло не так". А если это реюзабельный компонент, то вообще-говоря непонятно, на какой платформе его придется запускать. Ну и если уж совсем никак, то можно написать свое расширение PHP, собрать dll или so, подключить к PHP и использовать в свое удовольствие.


      1. POPSuL
        09.06.2016 00:52

        А почему нет?


        [$b, $a] = [$a, $b]

        1. красивее чем list($b, $a) = [$a, $b];
        2. читабельнее чем list($b, $a) = [$a, $b];
        3. короче чем list($b, $a) = [$a, $b].


  1. phpclub
    02.06.2016 07:36

    Спасибо Илья — за развернутый ответ по PHP7.1

    Можно повлиять на те или иные изменения — пообщавшись автором ветки на DevConf'16

    Приглашаю тебя туда бесплатно — глядишь что-то и протолкнем под чаек.


    1. LionAlex
      02.06.2016 09:11
      +3

      И вообще, всем рекомендую этот доклад Дмитрия: интересный рассказ, как удалось добиться такого прироста производительности, много сишного кода, хардкор, все как вы любите. Слушал его на CodeFest'е, это был самый технический доклад из всех, на которых я успел там побывать.


    1. Fesor
      02.06.2016 10:44
      +1

      Можно повлиять на те или иные изменения

      нельзя) Только через процесс обсуждения в php-internals и RFC.


  1. taliban
    02.06.2016 11:18
    +1

    try {
        // to do something
    } catch (MyException | AnotherException $e) {
        // Handle these exceptions
    } catch (Exception $e) {
        // Handle this in a different way
    }

    Всегда думал что эти вещи должны решать интерфейсы


    1. alexkunin
      02.06.2016 14:46
      +2

      Если через интерфейсы, то все библиотеки должны определять исключения через интерфейсы. А если какие-нибудь разработчики супер-популярного компонента забили на это? Возвращаемся к нашим костылям с несколькими catch. А тут получилось компактно и наглядно.

      А вообще можно смотреть на это так:

      function toDoSomething() { /* ... */ }
      function handleTheseExceptions(MyException | AnotherException $e) { /* ... */ }
      function handleThisInADifferentWay(Exception $e) { /* ... */ }
      

      Т.е. фактически это была сигнатура функции… пусть даже только в воображении. Зато повторно используются концепции вроде Union Types.


      1. alexkunin
        02.06.2016 14:48
        +1

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


        1. samizdam
          02.06.2016 23:14

          Почему же нельзя? Я на оба повесил бы что-то вроде ClosingFileAndLoggableExceptionInterface
          С одной стороны удобный сахар, а с другой Union Types по сути поощряет лень и расшатывает в некотором смысле ООП.
          Имхо, неоднозначное улучшение.


          1. alexkunin
            03.06.2016 00:33
            +2

            Обобщите мне, пожалуйста, эксепшны из доктрины и из твига. ;) Я именно об этом случае говорил: у того, кто ловит эксепшны, нет контроля над их классами.

            Но вообще согласен, что тут решение довольно спорное — в том смысле, что весьма редкий юзкейз (ну, осмысленный).


            1. samizdam
              03.06.2016 00:44

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


              1. Fesor
                03.06.2016 00:53
                +2

                И пришлось бы в каком-то адаптере делать такое:


                // ...
                } catch (DoctrineException | TwigException $exception) {
                    throw new MyUnifiedException('something went wrong', $exception);
                }

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


            1. taliban
              05.06.2016 20:42
              -1

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


    1. impwx
      02.06.2016 15:40
      +2

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

      Проблема тут в том, что операции над типами — это фундаментальный функционал системы типизации как таковой. Если это добавлять, то сразу во всех местах, где используются типы. Реализовать только частный случай в блоке try, но не реализовать в типах аргумента функции — это раскладывание граблей. Будущие поколения разработчиков будут на них наступать и плеваться.


    1. bloknot
      06.06.2016 12:21

      А можете объяснить на конкретном примере, как это должно быть реализовано через интерфейсы? Сам использую конструкции вида try {} catch () {} catch () {}..., которые мне не очень нравятся


      1. Fesor
        06.06.2016 13:29
        +1

        иерархия типов. Вот и весь ответ.


      1. taliban
        06.06.2016 14:17
        +1

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