Команда разработчиков PHP рада сообщить о релизе PHP 7.0.

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

Abstract Syntax Tree

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

PHPNG

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

Scalar Type Hints

Добавлены четыре новые декларации для скалярных типов: int, float, string и bool. По умолчанию используется нестрогий режим проверки и данные будут приводиться к тому типу, что указан в декларации:

 

function add(int $a, int $b) {

    // is_int($a) — true

    // is_int($b) — true

    return $a + $b;

}

 

add(«1», «2»);

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

 

declare(strict_types=1);

 

function add(int $a, int $b) {

    return $a + $b;

}

 

add(1.5, 2.5);

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

В дополнение к пользовательским функциями, cтрогий режим проверки типа также влияет на функции стандартной библиотеки и расширений:

 

declare(strict_types=1);

 

$foo = substr(52, 1);

// Catchable fatal error: substr() expects parameter 1 to be string, integer given

Return Type Declarations

 

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

 

Краткий пример синтаксиса в действии:

 

function foo(): array {

    return [];

}

Здесь так же, как и для type-hint, можно объявить строгий режим. Дополнительные примеры можно найти в RFC.

 

Uniform Variable Syntax

 

Введён единый синтаксис переменных. Благодаря этому изменению следующие выражения стали корректными:

 

// support missing combinations of operations

$foo()[‘bar’]()

[$obj1, $obj2][0]->prop

getStr(){0}

 

// support nested ::

$foo[‘bar’]::$baz

$foo::$bar::$baz

$foo->bar()::baz()

 

// support nested ()

foo()()

$foo->bar()()

Foo::bar()()

$foo()()

 

// support operations on arbitrary (…) expressions

(…)[‘foo’]

(…)->foo

(…)->foo()

(…)::$foo

(…)::foo()

(…)()

 

// two more practical examples for the last point

(function() { … })()

($obj->closure)()

 

// support all operations on dereferencable scalars (not very useful)

«string»->toLower()

[$obj, ‘method’]()

‘Foo’::$bar

Но не обошлось и без потери обратной совместимости:

 

                        // old meaning            // new meaning

$$foo[‘bar’][‘baz’]     ${$foo[‘bar’][‘baz’]}     ($$foo)[‘bar’][‘baz’]

$foo->$bar[‘baz’]       $foo->{$bar[‘baz’]}       ($foo->$bar)[‘baz’]

$foo->$bar[‘baz’]()     $foo->{$bar[‘baz’]}()     ($foo->$bar)[‘baz’]()

Foo::$bar[‘baz’]()      Foo::{$bar[‘baz’]}()      (Foo::$bar)[‘baz’]()

Generator Return Expressions

 

Добавлена возможность возвращать значения из генераторов.

 

function gen() {

    yield «Hello»;

    yield » «;

    yield «Sun!»;

 

    return «Goodbye Moon!»;

}

 

$gen = gen();

 

foreach ($gen as $value) {

    echo $value;

}

// Hello Sun!

 

echo $gen->getReturn(); // Goodbye Moon!

Generator Delegation

 

Введён новый синтаксис yield from <expr>, позволяющий генераторам делегировать операции Traversable объектам и массивам.

 

function hello() {

     yield «Hello»;

     yield » «;

     yield «Sun!»;

     yield » «;

 

     yield from goodbye();

}

 

function goodbye() {

     yield «Goodbye»;

     yield » «;

     yield «Moon!»;

}

 

$gen = hello();

foreach ($gen as $value) {

     echo $value;

}

 

// Hello Sun! Goodbye Moon!

Anonymous classes

 

Добавлена поддержка анонимных классов.

 

Они могут быть использованы вместо полного определения класса для одноразовых объектов:

 

(new class extends ConsoleProgram {

    public function main() {

       /* … */

    }

})->bootstrap();

Closure::call

 

PHP7 добавляет легкий способ переопределить $this для анонимной функции прямо во время вызова с помощью Closure::call().

 

class A {

    private $x = 1;

}

 

// Pre PHP 7 code

$getXCB = function() {return $this->x;};

$getX = $getXCB->bindTo(new A, ‘A’); // intermediate closure

echo $getX();

 

// PHP 7+ code

$getX = function() {return $this->x;};

echo $getX->call(new A);

Throwable Interface

 

Изменена иерархия исключений. А именно, введён интерфейс Throwable, который реализуют два базовых исключения: Exception и Error. Пользовательские классы не могут реализовывать этот интерфейс.

 

Таким образом, новая иерархия выглядит вот так:

 

interface Throwable

Exception implements Throwable

Error implements Throwable

TypeError extends Error

ParseError extends Error

AssertionError extends Error

Unicode Codepoint Escape Syntax

 

Добавлен новый экранирующий символ \u, который позволяет указывать специфические unicode-символы внутри PHP-строк:

 

echo «\u{aa}»; // ª

echo «\u{0000aa}»; // ª (same as before but with optional leading 0’s)

echo «\u{9999}»; // 香

Combined Comparison (Spaceship) Operator

 

Добавлен новый оператор комбинированного сравнения: (expr) <=> (expr). Он возвращает 0, если оба операнда равны, 1 в случае, когда левый операнд больше правого и -1, если правый больше левого.

 

echo 1 <=> 1; // 0

echo 1 <=> 2; // -1

echo 2 <=> 1; // 1

Group Use Declarations

 

Добавлена возможность группировки use деклараций.

 

// Before:

use Doctrine\Common\Collections\Expr\Comparison;

use Doctrine\Common\Collections\Expr\Value;

use Doctrine\Common\Collections\Expr\CompositeExpression;

 

// After:

use Doctrine\Common\Collections\Expr\{ Comparison, Value, CompositeExpression };

Null coalesce operator

 

Ещё один новый оператор — ??, который возвращает левый операнд, если тот не имеет значение NULL, в противном случае возвращается правый операнд. В отличии от короткого тернарного оператора ?:, он работает как isset().

 

// Fetches the value of $_GET[‘user’] and returns ‘nobody’

// if it does not exist.

$username = $_GET[‘user’] ?? ‘nobody’;

// This is equivalent to:

$username = isset($_GET[‘user’]) ? $_GET[‘user’] : ‘nobody’;

 

// Coalesces can be chained: this will return the first

// defined value out of $_GET[‘user’], $_POST[‘user’], and

// ‘nobody’.

$username = $_GET[‘user’] ?? $_POST[‘user’] ?? ‘nobody’;

Прочие изменения

 

Особо стоит отметить, что из PHP была удалена вся функциональность помеченная устаревшей в версиях 5.x.x, включая расширения ereg и mysql.

 

Следующие возможности объявлены устаревшими и будут удалены в будущих версиях:

 

Конструкторы классов в стиле PHP 4.

Статические вызовы нестатических методов.

Опция salt для password_hash().

Опция capture_session_meta для SSL context.