Это первая часть нашей минисерии статей «Чего ждать от PHP7». Читать часть 2

Как многие из вас, вероятно, знают, было принято RFC о согласовании названия следующей основной версии PHP, которая будет называться PHP7. Вы можете почитать об этом в моем PHP5 timeline.

Независимо от ваших чувств по поводу этой темы, PHP7 — это свершившийся факт, и он придет в этом году! RFC с таймлайном выпуска PHP7.0 прошло практически единогласно (32 к 2), сейчас разработчики подошли к стадии заморозки фич, а первый релиз-кандидат (RC) мы увидим уже в середине июня.

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

Ответ: посмотрим. Продолжайте читать и узнаете подробности.

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

Давайте углубимся в детали.

Исправления несоответствий


К сожалению, тикеты про needle/haystack так и не были решены. Тем не менее, прошли два очень важных RFC. Так что не стоит терять надежды на приход столь необходимой последовательности и ожидаемого синтаксиса.

Крупнейшим (и самым незаметным) стало добавление абстрактного синтаксического дерева (Abstract Syntax Tree — AST), являющегося промежуточным представлением кода во время компиляции. С AST core-разработчики смогут лучше обрабатывать пограничные случаи, устранять несоответствия в поведении, а также проложить путь для удивительных вещей в будущем, например, можно будет создавать еще более производительные акселераторы.

Также был введен единый синтаксис переменных, который может причинить много проблем с миграцией на PHP7. Он решает многочисленные несоответствия в вычислении выражений. Например, возможность вызывать анонимные функции, привязанные к параметрам через ($object->closureProperty)(), а также добавляет возможность вызывать цепочки статических методов:

class foo { static $bar = 'baz'; }
class baz { static $bat = 'Hello World'; }

baz::$bat = function () { echo "Hello World"; };

$foo = 'foo';
($foo::$bar::$bat)();

Однако, кое-что все же поменялось. В частности, семантика использования переменных переменных/свойств.

До PHP7, $obj->$properties['name'] было доступом к свойству, имя которого входило в значение, хранящегося по ключу name массива $properties. Теперь же, доступ будет осуществляться к значению по ключу name массива, который, в свою очередь, определяется значением параметра $properties в объекте.

Или, чтобы быть более кратким, если мы принимаем это утверждение:

$obj->$properties['name']

То в PHP5.6, оно будет интерпретировано как:

$obj->{$properties['name']}

А в PHP 7:

{$obj->$properties}['name']

Хотя и использование переменных-переменных, как правило, является пограничным случаем, и весьма неодобряемый сообществом, переменные-параметры — гораздо большая редкость в моей практике. Однако, вы можете легко обойтись без проблем с миграцией, если будете использовать фигурные скобки (как в примерах выше) для обеспечение аналогичного поведения между PHP5.6 и PHP7.

Производительность


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

На текущий момент дела обстоят следующим образом: PHP7 находится на одном уровне с HHVM, написанным фейсбуком, который работает в качестве Just In Time (JIT) компилятора, переводящего PHP-код в машинные инструкции.

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

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

Изменения, ломающие обратную совместимость


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

Однако, также как и изменение поведения в связи с вводом Uniform Variable Syntax, большая часть нововведений являются незначительными, например, отлавливаемые фатальные ошибки при вызове метода у не-объекта:

set_error_handler(function($code, $message) {
  var_dump($code, $message);
});

$var = null;
$var->method();
echo $e->getMessage(); // Fatal Error: Call to a member function method() on null
echo "Hello World"; // Still runs

Кроме того, APS и теги script были удалены, вы больше не сможете использовать <% и <%=, или `<script language="php”>` и их закрывающие теги %>, </script>.

Другие, гораздо более серьезные изменения, находятся в RFC об удалении ВСЕЙ устаревшей (deprecated) функциональности.

Особо стоит отметить исключение из стандартной поставки расширения posix-совместимых регулярных выражений ext/ereg (не рекомендовано к использованию в 5.3) и старого ext/mysql расширения (заменено на новое в 5.5).

Одним из других минорных изменений является запрет на использование множественного default в операторе switch. PHP до версии 7 разрешал делать так:

switch ($expr) {
    default:
         echo "Hello World";
         break;
    default:
         echo "Goodbye Moon!";
         break;
}

Это приведет к выполнению только последнего. PHP7 же выдаст ошибку:

Fatal error: Switch statements may only contain one default clause

Новые Возможности


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

Скалярный type-hint и возвращаемые значения


Я собираюсь начать с наиболее спорного момента, который был добавлен в PHP7: Scalar Type Hints. RFC на добавлении этой функции почти прошло голосование, но на автора настолько повлияли споры об этом, что он решил покинуть PHP-разработку, а также снял RFC с голосования. За этим последовало еще несколько, с конкурирующими реализациями. Было много общественных волнений, которые в конечном счете закончились (положительно) и оригинальная версия RFC была принята.

Для вас, конечных пользователей, это означает, что вы можете использовать type-hint со скалярными значениями. А именно: int, float, string и bool. По умолчанию функция работает в нестрогом режиме, а значит они будут просто приводить исходный тип в значение, указанное в подсказке типа. Например, если вы передали в функцию int(1), которая требует нецелочисленное число, то оно будет приводиться к float(1.0). И наоборот: передавая в функцию, требующую целого числа, float(1.5), то будет приходить значение int(1). Пример:

function sendHttpStatus(int $statusCode, string $message) {
     header('HTTP/1.0 ' .$statusCode. ' ' .$message);
}

sendHttpStatus(404, "File Not Found"); // integer and string passed
sendHttpStatus("403", "OK"); // string "403" coerced to int(403)

Вы можете включить режим строгой типизации declare(strict_types=1); в верхней части файла и он гарантирует вам, что любой вызов функций, сделанный в этом файле, будет строго придерживаться определенного типа. Это произойдет именно в том файле, где вызван declare, а не в том файле, где была определена вызываемая функция.

Если типы не совпадут, это приведет к выбросу отлавливаемой фатальной ошибки:

declare(strict_types=1); // должно быть на первой строчке

sendHttpStatus(404, "File Not Found"); // integer и string переданы
sendHttpStatus("403", "OK"); 

// Catchable fatal error: Argument 1 passed to sendHttpStatus() must be of the type integer, string given

PHP7 также поддерживает тип возвращаемого значения, который может принимать все те же типы в качестве аргументов. Синтаксис будет как и в hack, двоеточие с аргументом-суффиксом перед скобкой:

function isValidStatusCode(int $statusCode): bool {
    return isset($this->statuses[$statusCode]);
}

В данном примере : bool указывает на то, что функция вернет булево значение.

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

Комбинированный оператор сравнения


Моим любимым дополнением в PHP7 является добавление комбинированного оператора сравнения, <=>, также известного как Spaceship-оператор. Я могу казаться пристрастным, но он действительно крут, и хорошо сочетается с операторами > и <.

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

Наиболее распространенное его использование заключается в callback'ах сортировок:

// Pre Spacefaring^W PHP 7
function order_func($a, $b) {
    return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
}

// Post PHP 7
function order_func($a, $b) {
    return $a <=> $b;
}

Далее


Мы проанализировали некоторые из наиболее важных исправлений несоответствий поведения и посмотрели на две новые возможности PHP7.

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

P.S. А пока вы ждете, почему бы не поделиться своими мыслями по поводу того, что будет самым ожидаемым в PHP7? Или может быть есть вещи, которые не хотелось бы видеть в языке?

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


  1. DmitryKoterov
    13.05.2015 07:57
    +9

    Хостеров, не желающих обновлять php5, можно понять. А как им еще быть, если функцию php.net/htmlspecialchars в 5.4 сломали, да так, что починили только в 5.6? На минуточку: если сайт сделан не в кодировке utf-8, а в однобайтной, то все существующие в нем вызовы htmlspecialchars в 5.4 и 5.5 начинают возвращать пустоту, если в строке есть хотя бы один байт с кодом 128+ (например, с русскими буквами). Думается, у хостеров однобайтных сайтов должно быть довольно много: кто еще пользуется их услугами, как не олдскульные юзеры…

    Наверное, ни одно другое действие не способствовало процветанию utf8 так сильно, как этот вопрющий баг. Впрочем, карму php оно тоже попортило знатно.


    1. Alexufo
      13.05.2015 09:11
      +1

      А в чем проблема то в обновлениях хостерам? Какая им разница что там где сломали в php?
      У меня на виртальном версии от 5.2 до 5.6. И неделю назад объявили об отказе о поддержке 5.2


      1. lubezniy
        13.05.2015 13:58
        +1

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


        1. Alexufo
          14.05.2015 00:52
          +1

          Подождите, вы меняете сами версию php. Кто и где сейчас из хостеров принудительно менят php юзеру. Да в 5.4 сломали, ну 5.4 случайно не накатить. Причинно следственные связи ж налицо.


          1. lubezniy
            14.05.2015 10:16
            -1

            Как-то я случайно поменял с 5.4 на 5.6… при очень неосторожном обновлении Debian. Хоть и не хостер, но разработчики на проекте ругались долго.


            1. Alexufo
              14.05.2015 10:33
              +5

              в этом случае вы как раз хостер, который случайно обновил php. Скажите пацанам чтоб не выпендривались
              php.net/supported-versions.php
              С 1 января этого года версия 5.4 получает только секъюрные апдейты. с 2016 перестает делать и это.
              Сколько там функций то переписать времени нужно под 5.6? Не говна ли больше и головняка уже не будет:-)
              Версия 5.6 явно работает быстрее, я сужу по времени генерации страниц. Есть опкеш и т.п
              Я конечно не знаю всей вашей ситуации.


              1. lubezniy
                14.05.2015 12:27

                Уже переписывают.


    1. DmitryKoterov
      13.05.2015 14:39
      +3

      … я забыл добавить про htmlspecialchars(), что в 5.4 и 5.5 не существует решения этой проблемы, кроме как замена ВСЕХ htmlspecialchars на myhtmlspecialchars, и уже в функции myhtmlspecialchars() пробивать кодировку, отличную от utf8. А т.к. в большинстве старых скриптов вызовы htmlspecialchars() встречаются сотнями, это очень серьезный масштаб разрушений. Конфигурируемое через ini_set() дефолтное значение кодировки появилось только в 5.6.


      1. Casus
        13.05.2015 16:07
        -2

        Мы это исправили добавлением флага ENT_SUBSTITUTE.
        Ну а если в продукте сотни вызовов этой функции (что указывает на плохой код), то стоило бы сделать короткий алиас…


      1. Temirkhan
        13.05.2015 21:04

        Как вариант, можно ненадолго стать bad matha и воспользоваться grep и sed;


    1. DjOnline
      13.05.2015 18:37
      +1

      Полностью с тобой согласен, некоторые индусские разработчики PHP плевать хотели на обратную совместимость.
      А некоторых за описание этого бага даже минусовали ( habrahabr.ru/post/137296/#comment_4572064 )


  1. DmitryKoterov
    13.05.2015 08:01
    +3

    > PHP7 находится на одном уровне с HHVM
    > PHP7 не имеет JIT-компилятора
    М-мм… Вообще не на том же он уровне находится.

    А самым ожидаемым будет скалярный тайп-хинт, конечно.


    1. bolk
      13.05.2015 10:25
      +1

      Дим, тут имеется ввиду производительность, по всей видимости (такие тесты есть в интернете). По возможностям HHVM далеко опережает PHP7, по крайней мере пока, но «семёрка» — огромный шаг вперёд, шажище.

      А самым ожидаемым будет скалярный тайп-хинт, конечно.
      Возможно. Хотя у него масса недостатков, к сожалению, например, нельзя указать array|\ArrayObject или float|int.


      1. rmrevin
        13.05.2015 12:48

        Ещё непонятен момент с null. Если моя функция принимает или возвращает null|bool, например?


        1. bolk
          13.05.2015 14:56

          Ну, это-то как раз просто. Уже сейчас можно, например, писать так:

          function test(callable $func = null) {
          // …
          }
          


        1. turbo_exe
          13.05.2015 16:34
          +1

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


          1. Blumfontein
            13.05.2015 18:19
            +1

            >> функция должна возвращать только один тип данных

            Не согласен. Вам в БД же не выскакивает ошибка, когда вы вставляете в поле с foreign key значение null. Null — это такое значение, которое возможно в любом наборе данных.


            1. delmot
              14.05.2015 00:26

              Say 'No' to null


            1. turbo_exe
              18.05.2015 22:23
              +1

              на тему null-значений в sql есть отдельный холивар.


              1. Blumfontein
                19.05.2015 08:04

                Без null любая миграция превращалась бы в боль и страдания.


      1. Fesor
        15.05.2015 10:38

        array|\ArrayObject

        И хорошо что не могут. По идее ArrayObject должен подпадать под array, то что сейчас это не так это отдельная история. В любом случае массивы это не скаляры и такое поведение было уже давно, а RFC с тайп хинтингом для скаляров не призвано было пофиксить проблемы с уже существующими вещами. А float|int вообще не имеет никакого смысла. float норм, покрывает собой int. Значит только его и юзать. Сама идея объединения типов нарушает идею тайп хинтинга.


        1. bolk
          15.05.2015 11:00

          По идее ArrayObject должен подпадать под array, то что сейчас это не так это отдельная история.
          По идее array должен попадать под \Iterable, но не попадает, примитивный тип, отдельная история, да.

          А float|int вообще не имеет никакого смысла. float норм, покрывает собой int. Значит только его и юзать. Сама идея объединения типов нарушает идею тайп хинтинга.
          Да, float|int бесполезно, признаю?. Объединение типов полезно было бы на стыке примитивов и ООП.


          1. Fesor
            15.05.2015 11:15

            ну так те же map/reduce работают только с массивами… Ну и опять же есть определенные отличия. Скажем массивы в PHP при изменении в функциях копируются (CoW), если конечно не передаются по ссылке. Это упрощает жизнь и делает их… своего рода immutable штуками, а вот что делать с ArrayObject?


  1. AxisPod
    13.05.2015 08:05
    -6

    А тупо падать в бесконечной рекурсии разучится, говорить-то начнет чего-нить?


    1. bolk
      13.05.2015 10:28
      +9

      Да.

      bolk@MacBook-Pro ~$ /opt/php-7.0a/bin/php -r '$a = function() use(&$a) { $a();}; $a();'

      Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in Command line code on line 1


      1. remal
        13.05.2015 13:15
        -2

        Эм… Это и есть «тупо падать». По такому сообщению понять причину ошибки невозможно.


        1. bolk
          13.05.2015 14:55
          +5

          «Тупо падать» это вот:

          bolk@MacBook-Pro ~$ php -r '$a = function() use(&$a) { $a();}; $a();'
          Segmentation fault: 11

          bolk@MacBook-Pro ~$ php -v
          PHP 5.6.8 (cli) (built: Apr 30 2015 07:22:26)


          1. remal
            13.05.2015 16:46
            -3

            Это никак не отменяет того факта, что понять причину ошибки невозможно.


  1. Blumfontein
    13.05.2015 08:18
    +15

    $obj->$properties['name'] проинтерпретировал сначала как $obj->properties['name'] (без знака доллара у properties) и долго не мог вкурить, о чем это автор говорит =)


  1. borNfree
    13.05.2015 09:06

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


    Стоит отметить, что автором была вот эта девушка, один из самых активных контрибьюторов PHP.


    1. Gordon01
      13.05.2015 12:08

      А в ее бложике blog.ajf.me/2015-02-15-i-quit говорится что просто надоело тратить на ПХП много времени.


  1. Viacheslav01
    13.05.2015 09:12
    +5

    class foo { static $bar = 'baz'; }
    class baz { static $bat = 'Hello World'; }
    
    baz::$bat = function () { echo "Hello World"; };
    
    $foo = 'foo';
    ($foo::$bar::$bat)();
    


    Только мне подобное внушает ужас?


    1. ZhukV
      13.05.2015 09:35
      -9

      Ну, это наверное потому что это PHP ;)

      на самом деле, можно очень много чего такого придумать, что потом разработчик будет один час на 5 строчках голову ломать, и при этом, код вроде нормальный ;)


      1. dim_s
        13.05.2015 11:09

        Просто "::" и "->" стали бинарными операторами.


    1. bolk
      13.05.2015 10:30
      +4

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


      1. Viacheslav01
        13.05.2015 10:44

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


        1. bolk
          13.05.2015 10:47
          +1

          ОМГ. Обычная штука, ничего странного, какие ещё побочные эффекты? Просто в ПХП это раньше не работало, теперь работает.


        1. FractalizeR
          13.05.2015 10:49
          +2

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


          1. sferrka
            13.05.2015 11:11
            +1

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


            1. FractalizeR
              13.05.2015 12:34
              +1

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

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


          1. romy4
            13.05.2015 17:36

            вы в С++ variadic templates юзали и их предшественников из Boost, смотрели в код? Там же чёрт ногу сломит, понять сложно написанное. То же самое и про PHP: кто знает и способен юзать, тот будет. А пользователям классов и API не обязательно лазить по внутренностям.


            1. FractalizeR
              13.05.2015 18:13

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

              Совершенно неважно что это за код и откуда, если он просто иллюстрирует возможности языка


              1. romy4
                13.05.2015 19:01

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


                1. FractalizeR
                  13.05.2015 19:08
                  +1

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


                  1. romy4
                    13.05.2015 23:14

                    Теперь понял, спасибо :)


  1. OnYourLips
    13.05.2015 09:42
    +1

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

    На хостингах обычно используются сайты на популярных CMS к которым мы, обычные разработчики, отношения не имеем. Мы пишем софт на заказ и под него настроят то, что потребуется.
    Поэтому нам все равно, какая версия PHP стоит на хостингах. Да хоть PHP 5.3 или даже PHP 4.


    1. AlexeyK
      13.05.2015 13:00

      Я помню когда только появился php5 многие хостинги ухищрялись и ставили по 2 версии php, старый код с расширением .php обрабатывался 4 версией интерпретатора, а новый с расширением .php5 уже 5 версией.
      Тогда совместимость не ломалась, а разница между 4 и 5 версиями была не столь велика как например между php 5.2 и php 5.6.


  1. dvapelnik
    13.05.2015 10:31
    +1

    сейчас наблюдается переломный момент в плане обновления спецификаций, но сообщество как-то неоднозначно воспринимает их: если выхода ES6 ждут и пилят фичи, которые позволяют использовать сырой ES6 уже сейчас чтобы было легче перейти потом, то python3 и php7 либо дружно отвергают, либо не знают что будет
    дело в том, что предыдущих версиях ES все было сыро, а в ES6 будет круче? возможно, но тогда не могу согласиться с тем, что в актуальных версиях Python и PHP все отлично. наверное, дело не в этом
    а может разработчики пошли не тем путем, которого ожидало сообщество? а каким путем следовало пойти?


    1. OnYourLips
      13.05.2015 14:15
      +2

      C PHP7 все пошло тум путем, которого сообщество и хотело. Уже с июня можно будет брать бету и начинать делать новые проекты: к тому времени, как проект будет запущен, уже будет какой-нибудь 7.0.5.
      Более того, обратная совместимость отличная, и нужны лишь незначительные фиксы. В случае с python 3 же о совместимости не заботились.


      1. dvapelnik
        13.05.2015 14:55
        +1

        обычно если изменяется мажорный номер версии, то можно не говорить об обратной совместимости. да, код php4 может частично работать под php5 в виду того, что некоторые ф-ии поддерживаются, но они уже deprecated. аналогичную ситуацию следует ожидать и php5->php7. некоторые так пишут проекты, что даже в одной мажорной версии проект может не работать, но это зависит уже от разработчика. у меня крутится один такое проект, который работает только на php5.3 и для него приходится держать отдельный сервер чтобы не городить костылей с мультиверсионностью

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

        вот поиграться и покатать бету можно будет — это будет интересно

        аналогичная ситуация с ES6 — зоопарк браузеров все еще развивается и разрастается и не все обновляют свои «клиенты». снова нужно ждать пока появится лучшая поддержка стандарта браузерами

        в любом случае прогресс — это отлично!


        1. OnYourLips
          13.05.2015 15:40

          > обычно если изменяется мажорный номер версии, то можно не говорить об обратной совместимости

          > у меня крутится один такое проект, который работает только на php5.3 и для него приходится держать отдельный сервер чтобы не городить костылей с мультиверсионностью
          Не вижу причин держать дырявую версию PHP, а не просто переписать несколько мест в проекте.
          Чейнджлоги почитайте — мало чего изменилось. И мало изменится в PHP7. 99.9% кода будут совместимы.
          Просто запускаете тесты и правите баги.

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

          > а скорее всего будет склоняться к более стабильной версии. и именно из-за этого и будет замедляться переход на новую версию
          Она станет стабильной осенью. А минимальной полностью поддерживаемой версией станет 5.6.


          1. dvapelnik
            13.05.2015 17:29

            для того, чтобы запускать тесты нужно, как минимум, чтобы код был тестируемым. в упомянутом проекте код нетестируем и достался от немцев-рукоблудников. что говорить, если «смешались в кучу кони, люди» — php+html. как раз та ситуация, что работает — не трожь

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

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

            Она станет стабильной осенью. А минимальной полностью поддерживаемой версией станет 5.6.

            только на хостингах все равно останется php5.4-5.6 и php7 в роли экзотики


  1. matiouchkine
    13.05.2015 10:34
    +7

    Теперь я знаю, что говорить в ответ на вопрос «что такое php»: AST появилось в седьмой версии.


  1. impwx
    13.05.2015 11:11
    +1

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


    1. sferrka
      13.05.2015 11:18
      +1

      1. Обратную совместимость не сломали.
      2. Динамическая типизация никуда не делась, переменные все так же могут принимать любой тип.
      ИМХО, выгода PHP больше в скорости, интерпретируемости, и большой встроенной web-ориентированной библиотеке. Именно поэтому уже давно внедрены и классы и типы и т.д. Т.е. никто не держался никогда за отсутствие типов.


      1. impwx
        13.05.2015 11:43

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


    1. marapper
      13.05.2015 11:19
      +4

      Нет будет там проверки на этапе компиляции. Тайпхинтинг — не про это. Фактически, это сахар для

      function sendHttpStatus(int $statusCode, string $message) {
           header('HTTP/1.0 ' .$statusCode. ' ' .$message);
      }
      
      //non-strict
      function sendHttpStatus($statusCode, $message) {
           $statusCode = (int)     $statusCode;
           $message     = (string) $message;
           header('HTTP/1.0 ' .$statusCode. ' ' .$message);
      }
      
      //strict
      //declare(strict_types=1);
      function sendHttpStatus($statusCode, $message) {
           if (!is_int($statusCode)) {
                throw new InvalidArguments();
           }
           if (!is_string($message)) {
                throw new InvalidArguments();
           }
           header('HTTP/1.0 ' .$statusCode. ' ' .$message);
      }
      


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


      1. impwx
        13.05.2015 11:50

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

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


        1. sferrka
          13.05.2015 12:02
          +1

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

          Это не так. В PHP нет компиляции, поэтому единственный, кто может указать на неправильный вызов функции — IDE. Так она и отлично укажет.


          1. sferrka
            13.05.2015 12:06

            поэтому единственный

            Естесственно, имею в виду, единственный, до собственно выполнения программы.


        1. FractalizeR
          14.05.2015 10:37

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

          Это верно. Возможно, это должно нас всех стимулировать к написанию юнит-тестов по поводу и без :)


          1. impwx
            14.05.2015 11:02

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


  1. AlexeyK
    13.05.2015 12:42
    +5

    PHP RFC: Remove deprecated functionality in PHP 7

    ext/mysql (since PHP 5.5; use ext/mysqli or ext/pdo_mysql instead) REMOVED (PECL extension)

    Мне кажется, что только из-за удаления (переноса в PECL) mysql процесс миграции у хостинг-провайдеров может затянуться надолго. Количество кода, использующего старый mysql ext непропорционально велико.


    1. lubezniy
      13.05.2015 14:05
      +2

      По идее, достаточно скомпилировать соовтетствующее расширение как PECL-модуль, залить в нужный каталог и прописать в php.ini (на shared хостинге или на виртуальном сервере по умолчанию).


      1. sferrka
        13.05.2015 15:08

        Зачем PECL-модуль, достаточно просто интерфейс к mysqli на PHP написать.


        1. lubezniy
          13.05.2015 15:20
          +2

          Хостер, может, и напишет. А его клиентам это не факт, что надо.


          1. sferrka
            13.05.2015 15:24

            Так ведь и я о том же.


            1. lubezniy
              13.05.2015 15:47
              +1

              Теперь понял. Но, по идее, модуль на C должен работать побыстрее, чем дополнительный интерфейс к другому расширению.


              1. Blumfontein
                13.05.2015 18:34
                +2

                По-моему, клиентов шаред-хостингов скорость особо не волнует.


                1. lubezniy
                  13.05.2015 20:48

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


                  1. sferrka
                    13.05.2015 20:57

                    И для этого вы хотите загружать в каждый процесс PHP еще одно бесполезное расширение…


                    1. lubezniy
                      13.05.2015 21:02

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


                      1. sferrka
                        13.05.2015 21:24

                        чем при каждом открытии страницы интерпретировать такой же кусок на PHP.

                        Вы видимо не поняли, что такое интерфейс к mysqli. Но это не переписывание библиотеки на PHP.
                        Это, образно говоря:
                        function mysql_query($query, $link){
                            return mysqli_query($link, $query);
                        }
                        


                        1. lubezniy
                          13.05.2015 21:38

                          А всё равно интерпретатору при вызове скрипта (не важно, надо это или нет) придётся разбирать этот код. Он же принудительно включается через php.ini?


                          1. sferrka
                            13.05.2015 22:05

                            (тем более не бесполезное, а используемое большинством клиентов)

                            Бесполезное тем, что mysqli то тоже будет грузиться.
                            А всё равно интерпретатору при вызове скрипта (не важно, надо это или нет) придётся разбирать этот код.

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


                            1. lubezniy
                              14.05.2015 10:14

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


  1. DjOnline
    13.05.2015 18:19

    У меня есть вопрос по поводу производительности массивов в PHP и HHVM. Они стали быстрее в PHP7, и при этом они очень медленные в HHVM, где не вижу ускорения работы с ними, и к тому же они почему-то потребляют в 3 раза больше памяти по сравнению с тестовыми сборками PHP7.
    Spl так вообще в раз в 10 медленнее в HHVM по сравнению с обычными массивами и не показывают уменьшение памяти.

    Вот ссылка на мой бенчмарк 3v4l.org/8QZcN, по мотивам которого видимо можно написать целую статью о мифах и легендах. Например:
    — в последнем HHVM 3.6.0 доступ к массиву с числовым ключом, заданному через константу define, по прежнему медленее, чем доступ по числу, но быстрее чем по «string». Хвалёный компилятор не может константы define полностью приравнять к числам? В предыдущих hhvm, особенно 3.5.1 так вообще быле регрессия, define было в 2 раза медленнее «string».
    — аналогично в ночных сборках php7, define быстрее “string” но медленнее integer. Не зря существуют отдельные расширения для PHP, которые ускоряют константы. Когда же это появится в PHP из коробки?
    — php7 в этом тесте на массивах в 2 раза быстрее HHVM 3.6.0 на “string” и define, и в 1.5 раза на числовых индексах. У hhvm 3.6.0 наблюдается регрессия в скорости массивов почти в 2 раза по сравнению с предыдущими версиями.
    — spl в php 5.6.7 не быстрее define и integer, только лишь немного лучше по памяти до 25%
    — во всех версиях php ниже 5.6 доступ к массиву по константе define медленнее даже “string”

    Почему ни в PHP, ни в HHVM никак не сделают быстрые define? Почему до сих пор существуют костыли в виде apc_define_constants, hidef?


    1. REZ1DENT3
      13.05.2015 19:44

      действительно у HHVM проблемы с массивами :)
      http://3v4l.org/50UMD/perf#tabs

      Надо бы протестировать kPHP и сравнить результат

      ЗЫ, цель кода была усложнить вычисления


      1. DjOnline
        14.05.2015 11:52

        О как, с версии 5.3.24 и до 5.4.19 всё очень быстро, затем в 4 раза медленеее и в php7 в 2 раза медленее. Что они там поломали?


    1. dim_s
      14.05.2015 00:26
      +1

      Попробуйте объявлять константы через const, а не define.


  1. kvaki
    14.05.2015 09:27
    -8

    Ребят решил выучить php, что можете подсказать?


    1. Temirkhan
      14.05.2015 13:06
      +2

      Использовать ресурсы по назначению, например.


    1. Vedomir
      15.05.2015 07:11

      Google и другие поисковые системы. Книжные магазины в конце концов.


    1. REZ1DENT3
      15.05.2015 09:46

  1. Pasha4ur
    20.05.2015 12:25

    Здравствуйте

    Подскажите, пожалуйста, для чего здесь первая пара скобок?

    ($foo::$bar::$bat)();
    


    Изучаю php, но такого не встречал.

    {} — управляют порядком вычисления?

    {$obj->$properties}['name'] — здесь не нужен $ перед фигурной скобкой?


    1. iGusev Автор
      20.05.2015 12:47
      +1

      Подскажите, пожалуйста, для чего здесь первая пара скобок?
      ($foo::$bar::$bat)();

      Управляет приоритетом исполнения, также как и (2+2)*4. Сначала получаем значение статической переменной $bat из класса baz, а т.к. она является анонимной функцией, то тут же ее и исполняем. Можно было бы сделать и так:

      $qux = $foo::$bar::$bat;
      
      $qux();
      

      Продробнее можно прочитать тут и тут

      {} — управляют порядком вычисления?

      {$obj->$properties}['name'] — здесь не нужен $ перед фигурной скобкой?

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


  1. porutchik
    10.06.2015 10:49

    У нас в ihc.ru уже можно пробовать :) http://php7.for-test-only.ru/