PHP7 - что ожидать?
22.10.2015 г.
Дмитрий Золотов
Управление информатизации, РГПУ им. А.И.Герцена
dzolotov@herzen.spb.ru
Изменения в среде выполнения
Компиляция с использованием абстрактных синтаксических деревьев (AST)
JIT-компиляция в машинные коды и кэширование байт-кода в файлы
(сохраняются при перезапуске сервера)
Повышение производительности (используются фрагменты phpng)
Исключены альтернативные тэги начала кода <? и <script language=”php”>
Изменение приоритета операций разыменования и обращения к массиву:
теперь выполняются слева направо
$item->$properties["name"]. В php7 будет извлечен "name" от $item-
>$properties
Можно изменить порядок: $item->{$properties["name"]}
Унификация обращения к значениям:
круглые скобки - вызов функции (прямой или косвенный)
квадратные скобки - обращение к элементу массива (индекс или ключ)
Изменения в языке программирования
Изменения в языке программирования
Обращение к методу в переменной со значением null теперь приводит к
исключению.
$a = null;
try {
$a->test();
} catch (EngineException $e) {
echo $e->getMessage();
}
Изменения в языке программирования
Возможность перехвата Error и Throwable
o Throwable
Error
o ArithmeticError
o AssertionError
o DivisionByZeroError
o ParseError
o TypeError
Exception
o ...
Изменения в языке программирования
Запрещено использование нескольких default в switch:
switch ($expr) {
default:
echo "First default";
break;
default:
echo "Second default";
break;
}
Изменения в языке программирования
Анонимные классы
$a = new class implements Listener() {
function onProcess($e) { … }
}
Изменения в языке программирования
Null Coalesce:
$a = null;
$b = 10;
$c = 20;
echo $a ?? $b; //10
echo null ?? $c; //20
echo $a ?? $c ?? $b; //20
Реальный пример:
$config = $config ?? $this->config ?? static::$defaultConfig;
Изменения в языке программирования
Unicode-символы в строках:
"u{CODEPOINT}" (например, u{26BD}) - знак футбольного мяча
Коды можно посмотреть на emojipedia.org
Класс IntlChar и статические методы для манипулирования символами из
юникод (например, charName возвращает название символа, если функции
проверки принадлежности группе).
Типизация параметров и результатов
php5:
function sum($a,$b) { return $a+b; }
php7:
function sum(int $a, int $b): int { return $a+$b; }
По умолчанию - автоматическое приведение типов (для скалярных типов
возможно практически всегда)
Можно сделать строгую проверку соответствия: declare(strict_types=1),
должна быть первой инструкцией в файле
Встроенные скалярные типы
int - целое число
float - число с плавающей точкой
string - строка
bool - логическое значение
null возвращаться не может, если указан тип, но скоро ожидается синтаксис
nullable_types (вида ?тип)
Новый оператор сравнения
<=> (spaceship) - возвращает знак
-1 : значение слева меньше, чем значение справа
0: значение слева равно значению справа
+1: значение слева больше, чем значение справа
Условие Значение
a<b -1
a=b 0
a>b 1
Пакетный импорт
use TopClass {
SubClassClass1,
SubClassClass2,
Class3
};
вместо
use TopClassSubClassClass1;
use TopClassSubClassClass2;
use TopClassClass3;
Связывание замыкания с объектом класса
class Hello {
private $greeting = "Hello";
}
$to = function($name) { echo $this->greeting.", ".$name; }
$obj = new Hello();
$to->call($obj, "World");
//World передаётся параметров в замыкание, которое выполняется в
//контексте объекта
Перехват ошибок о несоответствии типов
<?php
set_error_handler(function ($code, $message) {
echo "ERROR $code: " . $message . "nn";
});
function a(ArrayObject $b){
return $b;
}
a("test");
Вызывает TypeErrorException и прерывает выполнение
Управление сессиями
При создании сессии можно указывать read_only и lazy_write
session_start(array("read_only"=>true)) - открывает сессию только
для чтения
session_start(array("lazy_write"=>true)) - обновляет сессию в
постоянном хранилище, только если были изменения
Variadic args (переменное количество параметров - из
PHP5.6)
function checkData($url, …$users) {
foreach ($users as $user) {
…
}
}
Параметры в конце списка могут быть указаны со значениями по умолчанию:
function test($name, $strict=false);
Использование генераторов
function generate_random() {
for ($i=1;$i<100;$i++) {
//или foreach (range(1, 100) as $i) {
yield rand();
}
}
$generator = generate_random();
foreach ($generator as $g) {
echo $g."n";
}
Вложенные генераторы (php7)
function first_numbers() {
yield 1;
yield from [2,3,4];
}
function all_numbers() {
yield 0;
yield from first_numbers();
yield 5;
}
Во вложенные генераторы можно передавать параметры
Возвращаемое значение из генератора
function generator() {
yield 1;
return 2;
}
$gen = generator();
echo $gen->getReturn(); //2
Traits(типажи)
Возможность переиспользования функций в нескольких классах:
trait Logger {
public function log($message) {
echo "Log: ".$message;
}
}
class FirstClass {
use Logger;
public function __construct() {
$this->log("Hello");
}
}
Traits - множественное наследование
trait A {
public function smallTalk() {
echo 'a';
}
public function bigTalk() {
echo 'A';
}
}
trait B {
public function smallTalk() {
echo 'b';
}
public function bigTalk() {
echo 'B';
}
}
Traits - множественное наследование
class Aliased_Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
Удаление устаревших функций
mysql -> mysqli
ereg ->preg
mssql -> pdo_mssql
sybase_ct
Новые функции
random_int($min,$max) - случайное число в интервале значений (обе
границы включаются)
random_bytes($len) - генерация последовательности из $len случайных
байт
intdiv($a,$b) - целочисленное деление
Возможные проблемы с расширениями
На текущий момент (22.10.2015 г.) не перенесены следующие расширения:
interbase
pdo_dblib
Где искать описание изменений
https://wiki.php.net/rfc
PHP Request For Comments - около 40 в обсуждении, 18 в черновиках, более
50 реализовано.
Использование замыканий и анонимных функций
$a = 10;
$func = function($b) use ($a) {
echo $a*$b;
}
$a = 5;
$func(5); //что отобразит?
Многопоточное выполнение (PThreads)
class Factorial extends Thread {
public $n;
public $result;
public function __construct($n) {
$this->n = $n;
}
public function calc($n) {
if ($n==1) return 1 else return $n*calc($n-1);
}
public function run() {
$this->result=$this->calc($this->n);
}
}
$fact = new Factorial(5);
$fact->start();
...
$fact->join();
echo $fact->result;
Асинхронное выполнение
ReactPHP:
EventLoop:
$loop = ReactEventloopFactory::create();
$factory = new ReactDnsResolverfactory();
$factory->create("8.8.8.8",$loop);
$promises = array();
$promises[] = $dns->resolve($hostname)->then(
function($ip) use ($hostname) { return "$hostname: $ip"; },
function($error) { return ""; })};
ReactPromiseall($promises)->then( function($hostnames) { echo $hostnames
});
$loop->run();
Обработка асинхронных событий
$loop = new ReactEventloopFactory::create();
$socket = new ReactSocketServer($loop);
$http = new ReactHttpServer($socket, $loop);
$http->on("request", function ($request, $response) {
$response->writeHead(200);
$response->end("Hellon");
}
$socket->listen(8080);
$loop->run();
Выполнение цепочки вызовов
$deferred = new ReactPromiseDeferred();
$promise = $deferred->promise()
->then(function($a) { return $a*2 })
->then(function($b) { return $b*3 })
->then(function($c) { echo "Result is ".$c; });
$deferred->resolve(4);
Возможна обработка потоков (аналог stream в java)
$loop = ReactEventLoopFactory::create();
$source = new ReactStreamStream(fopen("source.txt","r"),$loop);
$filter = new FilterLib();
$destination = new ReactStreamStream(fopen("dest.txt","w"),$loop);
$source->pipe($filter)->pipe($destination);
$loop->run();

PHP7 - что ожидать?

  • 1.
    PHP7 - чтоожидать? 22.10.2015 г. Дмитрий Золотов Управление информатизации, РГПУ им. А.И.Герцена dzolotov@herzen.spb.ru
  • 2.
    Изменения в средевыполнения Компиляция с использованием абстрактных синтаксических деревьев (AST) JIT-компиляция в машинные коды и кэширование байт-кода в файлы (сохраняются при перезапуске сервера) Повышение производительности (используются фрагменты phpng) Исключены альтернативные тэги начала кода <? и <script language=”php”>
  • 3.
    Изменение приоритета операцийразыменования и обращения к массиву: теперь выполняются слева направо $item->$properties["name"]. В php7 будет извлечен "name" от $item- >$properties Можно изменить порядок: $item->{$properties["name"]} Унификация обращения к значениям: круглые скобки - вызов функции (прямой или косвенный) квадратные скобки - обращение к элементу массива (индекс или ключ) Изменения в языке программирования
  • 4.
    Изменения в языкепрограммирования Обращение к методу в переменной со значением null теперь приводит к исключению. $a = null; try { $a->test(); } catch (EngineException $e) { echo $e->getMessage(); }
  • 5.
    Изменения в языкепрограммирования Возможность перехвата Error и Throwable o Throwable Error o ArithmeticError o AssertionError o DivisionByZeroError o ParseError o TypeError Exception o ...
  • 6.
    Изменения в языкепрограммирования Запрещено использование нескольких default в switch: switch ($expr) { default: echo "First default"; break; default: echo "Second default"; break; }
  • 7.
    Изменения в языкепрограммирования Анонимные классы $a = new class implements Listener() { function onProcess($e) { … } }
  • 8.
    Изменения в языкепрограммирования Null Coalesce: $a = null; $b = 10; $c = 20; echo $a ?? $b; //10 echo null ?? $c; //20 echo $a ?? $c ?? $b; //20 Реальный пример: $config = $config ?? $this->config ?? static::$defaultConfig;
  • 9.
    Изменения в языкепрограммирования Unicode-символы в строках: "u{CODEPOINT}" (например, u{26BD}) - знак футбольного мяча Коды можно посмотреть на emojipedia.org Класс IntlChar и статические методы для манипулирования символами из юникод (например, charName возвращает название символа, если функции проверки принадлежности группе).
  • 10.
    Типизация параметров ирезультатов php5: function sum($a,$b) { return $a+b; } php7: function sum(int $a, int $b): int { return $a+$b; } По умолчанию - автоматическое приведение типов (для скалярных типов возможно практически всегда) Можно сделать строгую проверку соответствия: declare(strict_types=1), должна быть первой инструкцией в файле
  • 11.
    Встроенные скалярные типы int- целое число float - число с плавающей точкой string - строка bool - логическое значение null возвращаться не может, если указан тип, но скоро ожидается синтаксис nullable_types (вида ?тип)
  • 12.
    Новый оператор сравнения <=>(spaceship) - возвращает знак -1 : значение слева меньше, чем значение справа 0: значение слева равно значению справа +1: значение слева больше, чем значение справа Условие Значение a<b -1 a=b 0 a>b 1
  • 13.
    Пакетный импорт use TopClass{ SubClassClass1, SubClassClass2, Class3 }; вместо use TopClassSubClassClass1; use TopClassSubClassClass2; use TopClassClass3;
  • 14.
    Связывание замыкания собъектом класса class Hello { private $greeting = "Hello"; } $to = function($name) { echo $this->greeting.", ".$name; } $obj = new Hello(); $to->call($obj, "World"); //World передаётся параметров в замыкание, которое выполняется в //контексте объекта
  • 15.
    Перехват ошибок онесоответствии типов <?php set_error_handler(function ($code, $message) { echo "ERROR $code: " . $message . "nn"; }); function a(ArrayObject $b){ return $b; } a("test"); Вызывает TypeErrorException и прерывает выполнение
  • 16.
    Управление сессиями При созданиисессии можно указывать read_only и lazy_write session_start(array("read_only"=>true)) - открывает сессию только для чтения session_start(array("lazy_write"=>true)) - обновляет сессию в постоянном хранилище, только если были изменения
  • 17.
    Variadic args (переменноеколичество параметров - из PHP5.6) function checkData($url, …$users) { foreach ($users as $user) { … } } Параметры в конце списка могут быть указаны со значениями по умолчанию: function test($name, $strict=false);
  • 18.
    Использование генераторов function generate_random(){ for ($i=1;$i<100;$i++) { //или foreach (range(1, 100) as $i) { yield rand(); } } $generator = generate_random(); foreach ($generator as $g) { echo $g."n"; }
  • 19.
    Вложенные генераторы (php7) functionfirst_numbers() { yield 1; yield from [2,3,4]; } function all_numbers() { yield 0; yield from first_numbers(); yield 5; } Во вложенные генераторы можно передавать параметры
  • 20.
    Возвращаемое значение изгенератора function generator() { yield 1; return 2; } $gen = generator(); echo $gen->getReturn(); //2
  • 21.
    Traits(типажи) Возможность переиспользования функцийв нескольких классах: trait Logger { public function log($message) { echo "Log: ".$message; } } class FirstClass { use Logger; public function __construct() { $this->log("Hello"); } }
  • 22.
    Traits - множественноенаследование trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; } } trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; } }
  • 23.
    Traits - множественноенаследование class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } }
  • 24.
    Удаление устаревших функций mysql-> mysqli ereg ->preg mssql -> pdo_mssql sybase_ct
  • 25.
    Новые функции random_int($min,$max) -случайное число в интервале значений (обе границы включаются) random_bytes($len) - генерация последовательности из $len случайных байт intdiv($a,$b) - целочисленное деление
  • 26.
    Возможные проблемы срасширениями На текущий момент (22.10.2015 г.) не перенесены следующие расширения: interbase pdo_dblib
  • 27.
    Где искать описаниеизменений https://wiki.php.net/rfc PHP Request For Comments - около 40 в обсуждении, 18 в черновиках, более 50 реализовано.
  • 28.
    Использование замыканий ианонимных функций $a = 10; $func = function($b) use ($a) { echo $a*$b; } $a = 5; $func(5); //что отобразит?
  • 29.
    Многопоточное выполнение (PThreads) classFactorial extends Thread { public $n; public $result; public function __construct($n) { $this->n = $n; } public function calc($n) { if ($n==1) return 1 else return $n*calc($n-1); } public function run() { $this->result=$this->calc($this->n); } } $fact = new Factorial(5); $fact->start(); ... $fact->join(); echo $fact->result;
  • 30.
    Асинхронное выполнение ReactPHP: EventLoop: $loop =ReactEventloopFactory::create(); $factory = new ReactDnsResolverfactory(); $factory->create("8.8.8.8",$loop); $promises = array(); $promises[] = $dns->resolve($hostname)->then( function($ip) use ($hostname) { return "$hostname: $ip"; }, function($error) { return ""; })}; ReactPromiseall($promises)->then( function($hostnames) { echo $hostnames }); $loop->run();
  • 31.
    Обработка асинхронных событий $loop= new ReactEventloopFactory::create(); $socket = new ReactSocketServer($loop); $http = new ReactHttpServer($socket, $loop); $http->on("request", function ($request, $response) { $response->writeHead(200); $response->end("Hellon"); } $socket->listen(8080); $loop->run();
  • 32.
    Выполнение цепочки вызовов $deferred= new ReactPromiseDeferred(); $promise = $deferred->promise() ->then(function($a) { return $a*2 }) ->then(function($b) { return $b*3 }) ->then(function($c) { echo "Result is ".$c; }); $deferred->resolve(4);
  • 33.
    Возможна обработка потоков(аналог stream в java) $loop = ReactEventLoopFactory::create(); $source = new ReactStreamStream(fopen("source.txt","r"),$loop); $filter = new FilterLib(); $destination = new ReactStreamStream(fopen("dest.txt","w"),$loop); $source->pipe($filter)->pipe($destination); $loop->run();