Переходим на PHP 7

php7-logo

Все те, кто слышал, что 12-го ноября выходит PHP 7, могут задаваться вопросами, чего ожидать и как подготовиться. Были внесены действительно большие улучшения языка в ядре и много новых интересных функций. Есть даже слухи и тесты о том, что PHP 7 будет примерно в два раза быстрее, чем PHP 5!

Давайте более подробно рассмотрим, что изменится.

Изменения производительности PHP 7

PHP 7 будет вдвое быстрее? Ни в коем случае, этого не может быть. Как может язык иметь такое радикальное различие в скорости? Хорошо, есть ряд крупных изменений в ядре PHP, которые значительно уменьшают нагрузку на CPU и использование памяти. Исполнитель работает быстрее и потребляет значительно меньше памяти. Для иллюстрации, программа, ранее потребовавшая 300 миллионов инструкций CPU в PHP 5, потребует всего лишь около 200 миллионов в PHP 7; приблизительно 30% сокращение использования CPU. Кроме того, компилятор генерирует более эффективный байт-код (примерно на 30% меньше строк). В итоге это приведёт к намного более эффективному (и быстрому) коду.

В дополнение к тем главным изменения производительности, сам синтаксический анализатор языка был полностью переписан с помощью надлежащих принципов информатики. Синтаксический анализатор теперь основан на модели Абстрактного синтаксического дерева. В абстрактном синтаксическом дереве каждый узел дерева обозначает конструкцию, происходящую в исходном коде. Синтаксис абстрактен в том смысле, что он не представляет каждую деталь, появляющуюся в реальном синтаксисе. Например, группировка круглых скобок будет неявной, и синтаксические конструкции, такие как if-условие-then, могут быть представлены как единый узел с тремя ответвлениями.

Лексический анализатор теперь контекстно-зависим с поддержкой полузарезервированных слов. Это означает, что зарезервированные слова могут теперь использоваться в качестве имён для атрибутов, констант и методов в классах, интерфейсах и трейтов. Например, теперь вы можете иметь метод класса под названием «for» или «if».

Проблемы миграции на PHP 7

Наиболее важный вопрос, который стоит рассмотреть, прежде чем начать работу над перемещением всех ваших приложений, будет «на какие проблемы мне стоит обратить внимание при миграции на PHP 7?» К счастью, на самом деле не так много проблем, с которыми вы должны столкнуться, если у вас нет кода, написанного в те времена, когда PHP 4 был крутым.

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

  • bool;
  • int;
  • float;
  • string;
  • null;
  • false;
  • true;
  • resource;
  • object;
  • mixed;
  • numeric.

Определённые синтаксические переменные в PHP 7 будут иметь другое значение, в сравнении с PHP 5. Это изменение упоминалось как Uniform Variable Syntax. Вы, конечно, должны избегать писать код по такому уродливому и не самодокументирующемуся образу в любом случае, но, к сожалению, у нас у всех есть устаревший код. Здесь нужно быть внимательным, потому что не будут брошены исключения компиляции, т. к. такой синтаксис всё ещё допустим, только с другим смыслом. Вот некоторые примеры:

$$foo['bar']['blah']
// В PHP5 означает: 
${$foo['bar']['blah']}
// В PHP7: 
($$foo)['bar']['blah']

/*************/

$foo->$bar['blah']
// В PHP5 означает: 
$foo->{$bar['blah']}
// В PHP7:
($foo->$bar)['blah']

/*************/

$foo->$bar['blah']()
//В PHP5 означает: 
$foo->{$bar['blah']}()
//В PHP7:
($foo->$bar)['blah']()

/*************/

Foo::$bar['blah']()
//В PHP5 означает: 
Foo::{$bar['blah']}()
//В PHP7:
(Foo::$bar)['blah']()

Много устаревших (deprecated) функций наконец удалены, в том числе:

  • Расширение EREG;
  • Старое mysql расширение (надо надеяться вы уже используете mysqli или PDO);
  • Статический вызов нестатических методов;
  • Оператор & (например: $x =& new X;) (новые объекты не могут быть присвоены по ссылке, прим. перев.);
  • Модификатор ‘eval’ для функции preg_replace;
  • Конструкторы в стиле PHP 4 теперь считаются устаревшими (deprecated) (т.е. методы конструктора с именем класса).

Новые функции PHP 7

PHP 7 имеет много по-настоящему классных и давно ожидаемых функций. Вот некоторые самые интересные.

Fatal Errors

Все действия, приводившие к «фатальным ошибкам» в PHP 5, теперь бросают отлавливаемые исключения в PHP 7. Это означает, что вы всегда можете завершить работу корректно.

Встроенное покрытие кода

Phpdbg отладчик, встроенный в PHP 5.6 (о котором, к сожалению, почти никто не знает) был расширен поддержкой покрытия кода, которая отлично подходит для модульного тестирования.

Описание типа возврата

Теперь вы можете явно указывать тип возврата функции:

class Foo {
    public function bar() : int {
        //do whatever
    }
}

В вышеупомянутом коде, если функция bar() вернёт значение не целочисленного типа, будет брошено исключение TypeError.

Scalar Type Hinting

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

class Foo {
    public function bar(int $a, string $b, float $c) {
        var_dump($a, $b, $c);
    }
}

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

$foo = new Foo();
$foo->bar(3.14, 3, 3);

// Выведет: int(3), string(1) '3', float(3)

Как же так получилось? Функция не следовала строго типам и не выдала исключение или, хотя бы, предупреждение, как можно было бы ожидать, а просто привела к указанным типам. Это называется принудительное приведение скалярных типов (Coercive Scalar Type Declaration). Печально, но есть способ заставить строго проверять типы:

declare(strict_types=1);

$foo = new Foo();
$foo->bar(3.14, 3, 3);

// Бросит TypeError

Отлично, проблема решена. Нет! Это, к сожалению, работает только в конкретном файле. Т.е. каждый файл должен явно объявить строгий ввод типов. Каждый файл. Вы не можете просто кинуть объявление в фронт-контроллере или загрузчике. Каждый файл.

Анонимные классы

Новый релиз PHP поддерживает анонимные классы. Вот как это выглядит:

class Foo {
    public function bar() {
        $x = new class($this) {
            private $blah;

            public function __construct(Foo $foo){
                $this->foo = $foo;
            }
        };
    }
}

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

Оператор объединения со значением Null

Оператор объединения с Null должен быть довольно изящной новой фичей. Он работает как типичный оператор объединения, который вы могли использовать в запросе MySQL. Вот как это выглядит:

$foo = $bar ?? $blah ?? $blorp;

Результатом $foo будет первое не null значение в цепочке. Этот оператор, безусловно, может сохранить несколько строк кода и сделать их чище; отлично подходит для присвоения значений по умолчанию.

Оператор «космический корабль»

Следующая крутая фича известна как оператор «космический корабль» (первоначально назывался Combined Comparison Operator).

// Код в PHP 5:
$result = ($a < $b) ? -1 : (($a > $b) ? 1 : 0);

// Может быть уменьшен до такого в PHP 7:
$result = $a <=> $b;

Вот список некоторых других функций, которых можно ожидать в PHP 7:

  • Zend Engine 3 (повышение производительности и поддержка 64-разрядного integer в Windows);
  • Процесс компиляции, основанный на AST;
  • Добавлено Closure::call();
  • Независимый от платформы побитовый сдвиг;
  • Делегация генераторов;
  • Возможность задания юникод символов в виде кодов;
  • Более простой и последовательный доступный CSPRNG API;
  • Сокращённый синтаксис для импорта нескольких элементов из пространства имён.

Источники:

Себастьян Бергман, создатель PHPUnit — Мюнхенская WebTech конференция 2015 года.

Примечание

Это авторский перевод статьи «Migrating to PHP 7» на русский язык.

Комментарии

  1. Fohroer пишет:

    Ruxe Engine будет поддерживать PHP 7?

  2. а нельзя ли будет declare(strict_types=1); указать в php.ini чтобы для всего сервера было по умолчанию?

  3. ТЕРМИКС пишет:

    В последнем примере знак вопроса пропущен (там где elseif).

  4. Трейдер пишет:

    Хочу заняться самообразованием, есть желание учить PHP. Но время от времени просматривая новости, думаю, не опоздаю ли я. То есть, все учебные пособия предполагают 5 версию. Допустим, отдам на обучение год или более, а потом не окажется ли что я все это зазря учил, если на момент предполагаемого окончания самообучения, версия 5 станет ненужной?

    • Иван пишет:

      Нет. Пхп7 только добавляет возможности, и убирает совсем устаревшие

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *