Php 7 что нового
Объявления скалярных типов введена в двух вариантах: принудительный (по умолчанию) и строгий. Следующие типы могут использоваться для объявления параметров (в обоих вариантах): строки ( string ), целые ( int ), числа с плавающей точкой ( float ) и логические значения ( bool ). Они дополняют аргументы других типов, введённых в PHP 5: имена классов, интерфейсов, array и callable .
<?php
// Принудительный режим
function sumOfInts ( int . $ints )
<
return array_sum ( $ints );
>
var_dump ( sumOfInts ( 2 , ‘3’ , 4.1 ));
Результат выполнения данного примера:
Для установки строгого режима, в самом начале файла необходимо поместить одну директиву declare . Это означает, что строгость объявления скалярных типов работает на уровне файла и не затрагивает весь остальной код. Эта директива затрагивает не только объявления параметров, но и возвращаемые значения функций (смотрите объявления возвращаемого типа), встроенные функции PHP и функции загруженных модулей.
Подробную документацию и примеры использования читайте в разделе декларация типов.
Объявления возвращаемых значений
В PHP 7 добавлена поддержка объявления возвращаемого типа. Аналогично как и объявления типов аргументов, объявление типа возвращаемого значения указывает, значение какого типа должна вернуть функция. Для объявления типа возвращаемого значения доступны все те же типы, что и для объявления типов аргументов.
function arraysSum (array . $arrays ): array
<
return array_map (function(array $array ): int <
return array_sum ( $array );
>, $arrays );
>
print_r ( arraysSum ([ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]));
Результат выполнения данного примера:
Полную документацию и примеры использования читайте в разделе про объявление возвращаемого типа.
Оператор объединения с null
Был добавлен оператор объединения с null ( ?? ), являющийся синтаксическим сахаром для достаточно распространённого действия, когда совместно используются тернарный оператор и функция isset() . Он возвращает первый операнд, если он задан и не равен null , а в обратном случае возвращает второй операнд.
<?php
// Извлекаем значение $_GET[‘user’], а если оно не задано,
// то возвращаем ‘nobody’
$username = $_GET [ ‘user’ ] ?? ‘nobody’ ;
// Это идентично следующему коду:
$username = isset( $_GET [ ‘user’ ]) ? $_GET [ ‘user’ ] : ‘nobody’ ;
// Данный оператор можно использовать в цепочке.
// В этом примере мы сперва проверяем, задан ли $_GET[‘user’], если нет,
// то проверяем $_POST[‘user’], и если он тоже не задан, то присваеваем ‘nobody’.
$username = $_GET [ ‘user’ ] ?? $_POST [ ‘user’ ] ?? ‘nobody’ ;
?>
Оператор spaceship (космический корабль)
Этот оператор предназначен для сравнения двух выражений. Он возвращает -1, 0 или 1 если $a , соответственно, меньше, равно или больше чем $b . Сравнение производится в соответствии с правилами сравнения типов PHP.
<?php
// Целые числа
echo 1 <=> 1 ; // 0
echo 1 <=> 2 ; // -1
echo 2 <=> 1 ; // 1
// Числа с плавающей точкой
echo 1.5 <=> 1.5 ; // 0
echo 1.5 <=> 2.5 ; // -1
echo 2.5 <=> 1.5 ; // 1
Определение констант массивов с помощью define()
Можно определить константу типа array с помощью функции define() . В PHP 5.6 такие константы можно было задавать только с помощью const .
echo ANIMALS [ 1 ]; // выводит «cat»
?>
Анонимные классы
Была добавлена поддержка анонимных классов с помощью new class . Их можно использовать тогда, когда нужен одноразовый класс и создавать полноценный класс, а потом его объект не имеет смысла:
<?php
interface Logger <
public function log ( string $msg );
>
class Application <
private $logger ;
public function getLogger (): Logger <
return $this -> logger ;
>
public function setLogger ( Logger $logger ) <
$this -> logger = $logger ;
>
>
$app = new Application ;
$app -> setLogger (new class implements Logger <
public function log ( string $msg ) <
echo $msg ;
>
>);
var_dump ( $app -> getLogger ());
?>
Результат выполнения данного примера:
Подробную документацию и примеры использования читайте в разделе про анонимные классы.
Синтаксис кодирования Unicode
Он принимает шестнадцатеричный код Unicode и записываем его в формате UTF-8 в двойных кавычках или формате heredoc. Любой корректный код будет принят. Ведущие нули по желанию.
Результат выполнения данного примера:
Closure::call()
Closure::call() является более производительным и коротким способом временного связывания области действия объекта с замыканием и его вызовом.
// До PHP 7
$getX = function()
$getXCB = $getX -> bindTo (new A , ‘A’ ); // промежуточное замыкание
echo $getXCB ();
Результат выполнения данного примера:
unserialize() с фильтрацией
Эта функциональность обеспечивает более высокий уровень безопасности при десериализации объектов с непроверенными данными. Это позволяет предотвратить возможную инъекцию кода, позволяя разработчику использовать белый список классов для десериализации.
// Преобразование всех объектов в __PHP_Incomplete_Class
$data = unserialize ( $foo , [ «allowed_classes» => false ]);
// Преобразование всех объектов, кроме MyClass и MyClass2 в __PHP_Incomplete_Class
$data = unserialize ( $foo , [ «allowed_classes» => [ «MyClass» , «MyClass2» ]]);
// Поведение по умолчанию принимает все классы (можно просто не задавать второй аргумент)
$data = unserialize ( $foo , [ «allowed_classes» => true ]);
IntlChar
Новый класс IntlChar добавляет новую функциональность в ICU. Класс определяет несколько статических методов и констант для манипулирования символами Unicode.
printf ( ‘%x’ , IntlChar :: CODEPOINT_MAX );
echo IntlChar :: charName ( ‘@’ );
var_dump ( IntlChar :: ispunct ( ‘!’ ));
Результат выполнения данного примера:
Для использования это класса необходимо установить модуль Intl.
Ожидания
Ожидания являются улучшенной, обратно совместимой версией старой функции assert() . Они позволяют делать предположения с нулевой стоимостью в промышленном коде и предоставляют возможность выбрасывать пользовательские исключения в случае провала ожидания.
Вместе тем, что старое API поддерживается, assert() теперь является языковой конструкцией, принимающей первым аргументом выражения, а не только строки ( string ) для оценки или логические значения ( bool ) для проверки.
<?php
ini_set ( ‘assert.exception’ , 1 );
class CustomError extends AssertionError <>
assert ( false , new CustomError ( ‘Сообщение об ошибке’ ));
?>
Результат выполнения данного примера:
Подробное описание этого функционала, а также инструкции для его конфигурирования для тестовых и промышленных сред, читайте в секции Ожидания раздела, посвящённому assert() .
Групповые объявления use
Классы, функции и константы импортируемые из одного и того же namespace , теперь можно группировать в одном операторе use .
<?php
// До PHP 7
use some \namespace\ ClassA ;
use some \namespace\ ClassB ;
use some \namespace\ ClassC as C ;
use function some \namespace\ fn_a ;
use function some \namespace\ fn_b ;
use function some \namespace\ fn_c ;
use const some \namespace\ ConstA ;
use const some \namespace\ ConstB ;
use const some \namespace\ ConstC ;
Выражение return в генераторах
Эта функциональность добавлена к генераторам, введённым в PHP 5.5. Она позволяет использовать оператор return в генераторах в качестве окончательного возвращаемого значения (возврат по ссылке недопустим). Это значение можно извлечь с помощью нового метода Generator::getReturn() , который можно использовать только после того, как генератор вернул все сгенерированные значение.
$gen = (function() <
yield 1 ;
yield 2 ;
foreach ( $gen as $val ) <
echo $val , PHP_EOL ;
>
echo $gen -> getReturn (), PHP_EOL ;
Результат выполнения данного примера:
Возможность явно получать окончательное значение генератора является очень полезной, так как позволяет клиентскому коду, использующему генератор, получать и обработать самое последнее значение генератора, после которого точно ничего больше не будет. Это сильно проще, чем вынуждать разработчика проверять, последнее ли значение вернулось и как-то по особенному его обрабатывать.
Делегация генератора
Теперь генератор может автоматически делегировать другому генератору, объекту класса, реализующий Traversable или массиву без необходимости писать в нем дополнительную обработку полученных значений. Достигается это с помощью конструкции yield from .
<?php
function gen ()
<
yield 1 ;
yield 2 ;
yield from gen2 ();
>
function gen2 ()
<
yield 3 ;
yield 4 ;
>
foreach ( gen () as $val )
<
echo $val , PHP_EOL ;
>
?>
Результат выполнения данного примера:
Функция целочисленного деления intdiv()
Новая функция intdiv() производит целочисленное деление операндов и возвращает его результат.
Результат выполнения данного примера:
Опции сессий
Теперь session_start() принимает массив опций, которые переопределят конфигурационные директивы сессии установленные в php.ini.
Также опции были расширены включённой по умолчанию опцией session.lazy_write, которая говорит PHP о том, что файл сессии надо перезаписывать, только если изменились данные сессии, и опцией read_and_close , которую можно задать только через session_start() для того, чтобы PHP закрывал сессию сразу же как прочитает её данные и не вносил в неё каких-либо изменений.
К примеру, для установки session.cache_limiter равным private и немедленному закрытию сессии после чтения её данных:
preg_replace_callback_array()
Новая функция preg_replace_callback_array() позволяет писать более чистый код, когда требуется использовать функцию preg_replace_callback() . До PHP 7 при необходимости обработать разные регулярные выражения разными функциями приходилось для каждой такой обработки писать отдельный вызов функции.
Теперь можно использовать одну функцию, передавая в неё ассоциативный массив, ключами которого являются регулярные выражения, а значениями — функции обратного вызова.
Функции CSPRNG
Были добавлены две новые кроссплатформенные функции для генерации криптографически безопасных строк и целых чисел: random_bytes() и random_int() .
Теперь функция list() всегда может распаковывать объекты, реализующие ArrayAccess
Ранее функция list() не гарантировала корректную обработку объектов, реализующих ArrayAccess . Теперь это исправлено.
Что нового в PHP 7
3 декабря 2015 года было объявлено о выходе PHP 7. Новая версия основывается на экспериментальной ветке PHP, которая изначально называлась phpng (PHPNextGeneration — следующее поколение), и разрабатывалась с упором на увеличение производительности и уменьшение потребления памяти.
Самой важной новинкой стало изменение ядра интерпретатора: теперь он называется PHPNG (Next Generation). Благодаря PHPNG удалось увеличить скорость обработки скриптов почти в двое по сравнению с PHP 5.x. Так же появился более эффективный менеджер памяти.
Прирост в скорости на практике хорошо виден на этой картинке. А для WordPress прирост в скорости выглядит так:
Синтаксические новинки PHP 7:
$a ?? » — isset и получение значения
Новый оператор слияния с NULL (NULL coalescing operator) ?? — это сокращение проверки isset и получения значения, если проверка пройдена.
Такая проверка часто была нужна в тернарном операторе ?: :
Так же, проверять можно по цепочке:
$a <=> $b — три сравнения сразу: больше, равно, меньше
Новый оператор сравнения <=> — «spaceship operator» (космический корабль). Сравнивает 2 переменные и возвращает результат сравнения в виде числа:
- -1 — если в сравнении подходит первый символ оператора <
- 0 — подходит второй символ =
- 1 — подходит третий символ >
Удобен для использования в usort() :
Можно использовать такой хак, чтобы не писать вложенных тернарных операторов:
define( ‘FOO’, [1,2] ); — массив в define константе
Константы могут содержать массивы еще с PHP 5.6. Но тогда их можно было передавать только через ключевое слово const. Теперь их можно указывать еще и через define() .
use name\space\; — группировка импорта
Теперь для краткой записи, импорт данных в наше пространство можно группировать:
int, float, bool — новые типы параметров функции/метода
Авто-проверка типа передаваемых данных в функции/методы, известная как «контроль типа» (typehint), продолжает развиваться и теперь понимает скаляры: int , float , bool , string . Раньше понимались только типы: array , имя класса или callable (с версии 5.4).
Режим строгой типизации
Если указан тип int и передать строку ‘123’ то проверка все равно будет пройдена, и php превратить строку в число.
Но что, если нужно получать именно число 123? Для этого можно включить режим строгой типизации, поместив в самое начало файла такую строку:
Это объявление должно быть первой строкой в файле, до выполнения какого-либо кода. Оно затрагивает только код файла и только вызовы и возвращаемые значения в этом файле.
Заметка: если строгая типизация указана в файле X, но не указана в файле Y и в файле Y вызывается функция из файла X. То вызов такой функции не будет подвержен строгой типизации!
int, float, bool, array — типы возврата функции/метода
Указывать принимаемый тип, можно еще с версии PHP 5.3. А вот указать какой тип функция/метод должна вернуть доступно только с версии PHP 7. Тут понимаются все типы: string , int , float , bool , array , callable , self (в методах), parent (в методах) , Closure , имя класса , имя интерфейса .
Возвращаемые типы при наследовании методов класса
При наследовании в классах, дочерние методы должны иметь такие же возвращаемые типы как и в родительском классе/интерфейсе:
Навороченный пример того, как можно писать в PHP 7
Тут сразу несколько новинок:
- принимаемый и возвращаемый тип;
- объединение и распаковка параметров с помощью . ;
- пример создания анонимной функции с указанием возвращаемого типа данных.
foo()(), $a::$b::$c, $$foo->bar — единый синтаксис: СЛЕВА НАПРАВО
Важная новинка! Теперь обращения к сложносочиненным переменным разбираются последовательно СЛЕВА НАПРАВО.
Примеры новых возможностей:
Примеры разницы старого и нового распознавания:
Старый код написанный с использованием <> для обработки переменных возможно не будет работать в новой версии PHP 7.
foreach — изменена логика работы
Теперь foreach не переключает автоматически внутренний указатель перебираемого массива, т.е. next() не работает автоматически:
Еще пример магического поведения в старых версиях:
foreach всегда работает с копией массива, т.е. результат foreach не будет меняться при изменении оригинального массива внутри foreach:
ОДНАКО, если значение массива передается по ссылке, то foreach всегда работает с исходным массивом, т.е. изменение массива внутри foreach изменит и результат foreach:
$class = new class<> — анонимные классы
Анонимные классы позволяют делать тоже самое что и обычные классы: передавать данные в конструктор, наследовать другие классы, использовать трейты и т.п.
Расширение классов работает как и ожидается:
Подробнее про анонимные классы читайте в документации.
yield . return 99; — возврат выражений в генераторах
Функции-генераторы появились в PHP 5.5. Но там можно было использовать return, только чтобы прервать работу генератора. Теперь return может возвращать выражение (значение/массив/другой генератор), а не только NULL. Но сделать это можно только в конце работы генератора.
Получить возвращенное значение можно методом getReturn() , но только по завершении работы генератора.
Возможность явно вернуть последнее значение упрощает работу с генераторами:
теперь не нужно проверять является ли значение последним, а просто вызываем getReturn() .
yield from func() — делегирование генераторов
Позволяет разбить сложный генератор на несколько простых.
Для этого используется новый синтаксис: yield from <expr> , где <expr> может быть значением (скаляром), массивом или другим генератором.
<expr> будет работать до тех пор, пока возвращает данные, затем выполнение продолжится в генераторе откуда <expr> был вызван. Смотрите пример:
Пример с массивом:
Пример с return из дочернего генератора:
Остальные новинки PHP 7.0
Синтаксис конструкторов в стиле PHP 4 (имя метода конструктора совпадает с именем класса) теперь считается устаревшим.
Статичные вызовы :: нестатичных методов теперь считаются устаревшими.
list() — изменение поведения. В PHP 5, list() устанавливал значения начиная с правого крайнего значения указанного массива, в PHP 7 параметры устанавливаются начиная с левого крайнего значения массива. Так же в PHP 5 list() умела разбивать строки на символы, в PHP 7 не работает со строками вообще.
Поддержка юникод управляющих (escape-) последовательностей. Т.е. в строках «» и heredoc можно использовать конструкцию \uXXXX для создания юникод символа. Вот так:
Класс IntlChar. Cодержит методы и константы для работы с юникодом.
Функция intdiv() — делит 2 числа и возвращает только целую часть от деления:
session_start() умеет получать параметры (стандартные настройки сессий из php.ini):
Функция preg_replace_callback_array() — альтернатива preg_replace_callback(). Позволяет передать в качестве обратной функции — массив [‘/regex’/ => callback, . ] :
Введение в PHP 7: Что добавлено, что убрано
Если вы какое-то время не работали с PHP, вы можете удивиться, куда же пропал PHP 6, почему мы перепрыгнули с PHP 5 сразу на PHP 7? Что ж, я буду краток, выпуск PHP шестой версии не состоялся. Главной особенностью версии 6 была поддержка символов Unicode, поскольку в основном PHP используется в веб-разработке, вебу же нужна поддержка Unicode, поэтому её реализация имела смысл.
Идея была в том, чтобы реализовать поддержку Unicode непосредственно в ядре. Такой подход должен был расширить возможности языка — от использования глупых эмоджи в качестве имен переменных и функций, до мощной функциональности интернациональных строк. Например, в случае, когда другой язык использует заглавные и прописные буквы отлично от английского языка или же при конвертации имени на китайском в имя на английском языке.
К сожалению, этот амбициозный план имел куда больше проблем, чем ожидалось. Большая часть кодовой базы должна была быть портирована для поддержки Unicode, как в случае ядра, так и в случае важных расширений, что оказалось утомительным и непростым делом. Это замедлило процесс разработки других возможностей языка, что расстроило многих PHP-разработчиков. Появились и другие барьеры, что привело к падению интереса к разработке встроенной поддержки Unicode, а со временем проект и вовсе оказался заброшенным.
А поскольку масса ресурсов, таких как книги и статьи, были написаны с использованием названия PHP 6 и поддержки Unicode, новой версии было решено присвоить имя PHP 7 — просто для того, чтобы избежать недопонимания.
Как бы там ни было, хватит копаться в мрачном прошлом. Давайте взглянем на то, что нового у нас появилось в PHP 7.
Войны за производительность, PHP 7 vs. PHP 5
Практически все обновления привносили небольшие улучшения производительности. Однако на этот раз производительность PHP, по сравнению с более ранними версиями, выросла куда более существенно, став одной из наиболее привлекательных особенностей PHP 7. Это было частью проекта “PHPNG” (“php new generation” или “php нового покления”, — прим. переводчика), затронувшего собственно сам Zend Engine.
Рефакторинг внутренних структур данных и добавление дополнительного этапа перед компиляцией кода в виде абстрактного синтаксического дерева — Abstract Syntax Tree (AST), привели к превосходной производительности и более эффективному распределению памяти. Цифры сами по себе выглядят многообещающе — тесты, выполненные на реальных приложениях показывают, что PHP 7 в среднем вдвое быстрее PHP 5.6, а также использует на 50% меньше памяти вовремя обработки запросов, что делает PHP 7 сильным соперником для компилятора HHVM JIT от Facebook. Взгляните на эту инфографику от Zend, которая отображает производительность для некоторых общеизвестных CMS и фреймворков.
Уменьшение потребления памяти позволяет более слабым компьютерам лучше обрабатывать запросы, предоставляя возможность выстраивания микросервисов вокруг PHP. Внутренние изменения, в частности реализация AST, также открывает возможности для будущих оптимизаций, которые могут ещё больше увеличить производительность. Новая собственная реализация JIT-компилятора разработана с намерением развития в будущих версиях.
Синтаксический сахар в PHP 7
В PHP 7 появилось несколько новых синтаксических штучек. Почему бы и не расширить некоторые возможности самого языка, если они предлагают лучший или более легкий способ написания приятного глазу кода?
Группировка объявлений импорта
Теперь мы можем группировать объявления импорта классов, находящихся в одном пространстве имён, в одной строке. Это поможет нам выровнять декларации неким, наделенным смыслом, образом или же просто сэкономит пару байт вашего кода.
В PHP 7 можно написать:
Или же, если вы предпочитаете многострочный стиль:
Null-коалесцентный оператор
Решает распространенную проблему в PHP. Она возникает в случае, если мы хотим присвоить значение переменной, которое присвоено другой переменной, но если последней переменной значение не было присвоено, то присвоить некое явное значение. Часто проявляется при работе с пользовательским вводом.
Можно использовать с цепочкой переменных:
Оператор “космический корабль”
Оператор “космический корабль” <=> позволяет проводить трехуровневое сравнение двух значений, позволяя понимать не только их равенство или неравенство, но и то, которое из них больше при неравенстве, возвращая 1,0 или -1.
В этом случае мы можем предпринимать различные действия в зависимости от того, как различаются значения:
Сравниваемые значения могут иметь тип integer, float, string и даже быть массивами. Как разные значения сравниваются друг с другом? Смотрите в документации.
Новое в PHP 7
Конечно, в PHP 7 появилась новая, впечатляющая функциональность.
Типы скалярных параметров и подсказки (hints) по возвращаемым типам
В PHP 7 расширили ранее существовавшее объявление параметров в методах (классах, интерфейсах и массивах) путем добавления четырех скалярных типов — целого (int), с плавающей запятой (float), логического (bool) и строкового (string) в качестве возможного типа параметра.
Кроме того, опционально мы можем указать тип результата, возвращаемого функцией или методом. Поддерживаются типы bool, int, float, string, array, callable, имя класса или интерфейса и parent (для методов класса).
Объявление типов позволит строить прозрачные приложения, избегая передачи и возврата неверных значений при работе с функциями. Другие плюсы — появление анализаторов статического кода и IDE, предлагающих более ясное отображение кода при отсутствии документирующих примечаний DocBlocks.
Поскольку PHP слабо типизированный язык, некоторые значения параметров и возвращаемых типов будут приводиться исходя из контекста. Если мы передаем значение “3” в функцию, имеющую объявленный параметр типа int, интерпретатор будет рассматривать его как целое и не сгенерирует ошибку. Если вас не устраивает такое поведение, вы можете работать в строгом режиме — strict mode — путем добавки соответствующей директивы.
Она устанавливается отдельно для каждого файла, поскольку глобальная опция разделила бы хранилища кода на такие, в которых файлы разрабатывались с включенной опцией и те, где она была отключена, что привело бы к непредсказуемому поведению при работе с кодом из двух хранилищ с разными настройками.
Исключения движка
С появлением исключений уровня ядра, фатальные ошибки, которые ранее могли привести к остановке выполнения скрипта, теперь могут быть легко перехвачены и обработаны.
Ошибки, такие как вызов несуществующего метода, теперь не остановят скрипт, вместо этого будет сгенерировано исключение, которое можно обработать в блоке try catch, что явно улучшает обработку ошибок в вашем приложении. Это важно для некоторых типов приложений, серверов и демонов, поскольку фатальные ошибки, в противном случае, вполне могли привести к необходимости их рестарта. Тесты в PHPUnit также должны стать более удобными в использовании, поскольку фатальные ошибки могли уронить весь тестировочный проект. Исключения, в отличие от ошибок, могут быть обработаны для каждого теста отдельно.
В PHP 7 появилось достаточно много новых классов исключений, призванных обрабатывать типы ошибок, с которыми вы можете столкнуться. Для обеспечения совместимости между версиями, добавлен новый интерфейс Throwable, он может быть реализован как исключениями уровня ядра, так и пользовательскими исключениями. Такой подход реализован с целью недопущения наследования базового класса исключений исключениями ядра, что привело бы к появлению исключений в прежде написанном коде, которых ранее не было.
До PHP 7 такой код привел бы к фатальной ошибке исполнения скрипта:
Анонимные классы
Анонимные классы — двоюродные братья анонимных функций, которые вы могли использовать при создании функциональности коротких и ясных объектов. Анонимные классы легко создаются и используются так же, как и обычные объекты. Вот пример из документации.
Использование анонимного класса:
Анонимные классы полезны при тестировании юнитами, в частности при мокинге (имитации поведения реального объекта — прим. переводчика) при тестировании объектов и сервисов. Их наличие позволит нам избежать использования больших мокинг-библиотек и фреймворков путем создания простого объекта, поддерживающего интерфейс, который мы можем использовать для мокинга.
Функции CSPRNG
Две новых функции для генерации крипографически безопасной строки и целых. Первая возвращает случайную строку длиной $len:
Вторая возвращает число в диапазоне $min… $max.
Синтаксис Escape-кода для Unicode
В отличие от многих других языков, до PHP версии 7, в PHP не было способа указать в строке escape-последовательность для Unicode символа. Теперь с помощью escape-последовательности \u можно генерировать такие символы с помощью их кода из набора UTF-8. Это лучше, чем непосредственная вставка символов, лучше контролируются невидимые символы и символы, имеющие графическое отображение отличное от значения:
Помните, что код, ранее работавший и использовавший пару символов \u, не будет корректно работать в версии 7 из-за изменившегося поведения.
Обновленные генераторы
Генераторы в PHP тоже получили несколько приятных новых возможностей. Теперь у них появился оператор return, который может быть использован для выдачи некоторого финального значения, актуального на момент завершения итерации. Его можно использовать для проверки корректности выполнения генератора. Например, узнать, выполнился ли он без ошибок, что позволит коду, вызвавшему генератор, корректно обработать любую возникшую ситуацию.
Больше того, генераторы могут возвращать и выдавать выражения из других генераторов. Таким образом, можно разбивать сложные операции на более простые.
Ожидания (expectations)
Ожидания (expectations) — улучшение функции assert() с сохранением обратной совместимости. Они позволяют использовать утверждения с нулевой стоимостью (zero-cost assertions) в рабочем коде и поддерживают возможность генерации пользовательского исключения при возникновении ошибки при отработке утверждения, что может быть полезно при разработке.
Функция assert() стала языковой конструкцией в PHP 7. Утверждения должны быть использованы только во время разработки и тестирования с целью отладки. Для настройки её поведения мы должны использовать две директивы.
- zend.assertions
1: генерируем и выполняем код (режим разработки) (значение по умолчанию)
0: генерирует код, но обходит его во время выполнения
-1: не генерирует код, делая его кодом с нулевой стоимостью (режим рабочего кода) - assert.exception
1: генерируется при ошибке утверждения путем создания соответствующего объекта исключения или же путем генерации объекта AssertionError, если такой объект не был создан
0: использует или генерирует Throwable так, как было описано выше, но генерируется только предупреждение (warning) на базе того объекта, а не генерация исключения с его помощью (поведение, совместимое с PHP 5)
Готовимся к переходу от PHP 5 к PHP 7
Появление версии PHP с номером 7 предоставило возможность изменения/обновления и даже удаления функциональности, которая считалась устаревшей или, некоторое время, уже ненужной. Такие изменения могут привести к проблемам с обратной совместимостью старых приложений.
Другая проблема, возникающая при появлении подобных версий, заключается в том, что библиотеки и фреймворки, которые для вас важны, могут не иметь обновлений, совместимых с новым релизом. Команда разработчиков PHP пыталась вносить изменения как можно в более высокой степени сохранив обратную совместимость для того, чтобы миграция на новую версию была как можно менее трудоёмкой. Относительно новые и вовремя обновляемые приложения, скорее всего, будет проще перевести на седьмую версию, тогда как для старых приложений необходимо взвешенное решение — стоят ли потраченные усилия полученных возможностей или же лучше и вовсе не обновляться.
Большая часть проблем невелики и могут быть легко устранены, в то время как другие могут потребовать куда больше времени и усилий. В целом, если вы видели предупреждения об использовании устаревших функций до установки PHP 7, то вы, скорее всего, увидите сообщения об ошибках, которые прекратят выполнение вашего приложения до их устранения.
Вас предупредили, так ведь?
Старые SAPI и расширения
Куда важнее тот факт, что были убраны старые и ненужные SAPI, такие как расширение mysql (но вы же его уже не используете, так?). Полный список расширений и возможностей, которые были удалены, вы можете посмотреть здесь и здесь.
Другие расширения и SAPI были портированы на PHP 7.
Однообразный синтаксис описания переменных
Это обновление привнесло некоторые изменения в части согласованности для конструкций переменная-переменная. Оно позволит использовать более прогрессивные выражения с переменными, что, в отдельных случаях, приведет к изменению поведения кода, как показано ниже:
Это изменит поведение приложений, получающих доступ к переменным указанным способом. С другой стороны, вы сможете выделывать вот такие фокусы:
Убраны тэги в старом стиле
Убраны или более некорректны открывающие/закрывающие тэги
Заменить их на корректные легко, но их использование в наше время выглядит несколько странно, не так ли?
Некорректные имена для классов, интерфейсов, трейтов
В результате добавлений, таких как типы возвращаемых значений и параметров, классы, интерфейсы и трейты больше не могут именоваться такими именами:
- bool
- int
- float
- string
- null
- true
- false
Подобное именование может привести к некорректной работе существующих приложений и библиотек, но легко поддаётся исправлению. Следующие имена тоже нежелательно использовать в выше названном качестве, поскольку они зарезервированы на будущее:
- resource
- object
- mixed
- numeric
Воздержитесь от использования этих слов в качестве имен, и вы сэкономите себе время впоследствии.
Полный список изменений, приводящий к несовместимости, можно посмотреть здесь.
Также вы можете использовать php7cc, этот инструмент проверит ваш код и отобразит потенциальные проблемы, которые могут возникнуть при переходе на PHP 7.
Но нет пути лучше, чем установить PHP 7 и увидеть всё воочию.
Потенциальные проблемы совместимости PHP 7
Совместимость инфраструктуры PHP 7
Многие сервисы хостинга добавили поддержку PHP 7. Это хорошая весть для провайдеров shared-хостинга, поскольку возросшая производительность позволит им увеличить число клиентских веб-сайтов без обновления железа, уменьшив текущие расходы и увеличив доходы. Что до клиентов, то они не должны ожидать резкого увеличения производительности в этих условиях, да и, говоря откровенно, shared-хостинг в любом случае не опция в случае приложения, ориентированного на производительность.
С другой стороны, сервисы, предлагающие частные виртуальные сервера или выделенные сервера, получат все прелести роста производительности. Некоторые PaaS-сервисы, такие как Heroku, давно поддерживают PHP 7, другие же, типа AWS Beanstalk и Oracle OpenShift, плетутся позади. Убедитесь на веб-сайте вашего PaaS-провайдера, есть ли у него поддержка PHP 7 или же она планируется в ближайшем будущем.
IaaS-провайдеры позволяют вам контролировать “железо” и устанавливать PHP 7 (или скомпилировать, если вам это больше нравится). Пакеты PHP 7 уже доступны для большинства IaaS-сред.
Совместимость программного обеспечения с PHP 7
В довесок к совместимости с инфраструктурой, вам также необходимо помнить о потенциальных проблемах совместимости с программным обеспечением. Известные CMS типа WordPress, Joomla и Drupal уже добавили поддержку PHP 7. Основные фреймворки, такие как Symfony и Laravel тоже сделали это.
Однако пришло время предостережений. Эта поддержка не распространяется на код третьих лиц в виде дополнений, плагинов, пакетов и т.п., к чему обращается ваш CMS или фреймворк. Проблемы могут быть, и ваша задача заключается в том, чтобы убедиться — всё готово для работы под PHP 7.
Для активных, поддерживающихся репозиториев, это не должно быть проблемой. Но заброшенные репозитории без поддержки PHP 7 могут сделать всё ваше приложение непригодным к использованию.
Будущее PHP
В PHP 7 был убран устаревший код, а также был дан зеленый свет новым возможностям и будущим улучшениям в области эффективности. Плюс, PHP вскоре должен получить оптимизацию производительности. Несмотря на частичную потерю обратной совместимости с предыдущими версиями, большинство возникающих проблем легко решаемы.
Библиотеки и фреймворки мигрируют на PHP 7, что приводит к появлению их новых версий. Я призываю вас попробовать семёрку и оценить полученные результаты. Может быть, ваше приложение уже совместимо с новой версией и готово работать на PHP 7, получая выгоды от его использования.
PHP 7 — глубокий взгляд
PHP 7 был выпущен 3 декабря 2015 года, и всё ещё остаётся много людей, которые не начали использовать его или не узнали о его удивительных особенностях — для них и написана данная статья. Впрочем, даже если вам это всё известно, вы могли бы узнать ещё что-то новое из этой статьи. Расмус Лердорф (создатель PHP) утверждает, что у приложений, работающих на PHP 7, производительность улучшена на 100% или более. Расход памяти также снизился, так что если вы работаете с высоконагруженными серверами, PHP 7 является весьма полезным обновлением для них. Одним из самых больших изменений в PHP 7 является переработанный Zend Engine (PHPNG), который теперь работает быстрее, расходует память меньше, и «зеленая» версия PHP, которая требует менее мощного железа для запуска кода.
Итак, что было удалено из PHP 7?
1) MYSQL:
Оригинальный модуль MySQL подвергался критике в PHP 5.5. Мы использовали такие функции, как mysql_connect() , mysql_query(). Настоятельно рекомендуется использовать улучшенный модуль MYSQL — MySQLi или же PDO для любых операций с базами данных. Если вы начинаете использовать PHP 7 (а вам лучше начать как можно скорее), то учтите, что оригинальный модуль было удален полностью. Но если вы хотите использовать оригинальный модуль MySQL, вы можете найти и установить его на https://pecl.php.net/. PECL является хранилищем для PHP-расширений, с каталогом всех известных расширений и предоставлением хостинг-услуг для загрузки и разработки расширений PHP.
2) POSIX-функции регулярных выражений:
PHP предлагает функции, которые являются специфическими для определенного вида регулярных выражений — функций POSIX-регулярных выражений и регулярных выражений в PERL-стиле. На PHP 7 вы не можете использовать POSIX-функции, такие как ereg(), ereg_replace(), split(), вместо этого вы должны использовать функции PERL-совместимых регулярных выражений (PCRE), такие как preg_match(), preg_replace(), preg_split(). Если вам еще нужны функции POSIX-регулярных выражений в вашем приложении, вы можете также установить их из https://pecl.php.net/.
3) Альтернативные PHP-теги:
В PHP 7, вы больше не можете применять ASP-теги, например или и теги скриптов HTML .
4) Присвоение объекта по ссылке:
Вот так больше нельзя писать в PHP 7 — «$car =& new Car()» — уже в PHP 5 это не было нужно, потому что объекты и так всегда присваиваются по ссылке.
5) Комментарии в файлах конфигурации:
Это считалось устаревшим ещё в PHP 5.3, а с PHP 7, вы больше не можете использовать ‘#’ для комментариев в INI-файлах. Требуемый символ является стандартной точкой с запятой ‘;’
6) SALT-ОПЦИЯЯ В PASSWORD_HASH ():
Опция SALT для функции password_hash() удалена, чтобы предотвратить создание разработчиками собственных солей — ведь это может быть небезопасным.
Вы можете узнать больше здесь — https:// wiki.php.net/ rfc/remove_deprecated_ functionality _in _php7
Итак, мы перечислили то, что было удалено в PHP 7, а что было добавлено?
Новые возможности PHP 7:
«Космический корабль» — оператор
Оператор «космический корабль» (так называемый «комбинированный оператор сравнения») используется для сравнения двух выражений. Он возвращает -1, 0 или 1, при проверке типа «левое выражение меньше правого выражения». Это также работает со строками. Этот оператор в основном используется в функциях обратного вызова, например, в пользовательской сортировке значений.
Оператор объединения по Null — ??
С оператором объединения по Null, отпадает необходимости использовать такие функции, как isset(). Он просто возвращает первый операнд, если он не Null, в противном случае возвращает последний. Можно также задать цепь значений с помощью этого оператора. Он использует первое не-Null значение, которое попадется, начиная с левой стороны. Обратите внимание, что это только для значений Null — а не для, например, пустых строк, которые не равны Null в PHP.
Объявление массивов-констант через define()
Массивы-константы теперь могут быть объявлены через define(). В PHP 5.6, они могли быть объявлены только через const.
Unicode — поддержка смайликов
Многие любят использовать смайлики для общения с друзьями, с PHP 7 вы можете использовать смайлики в вашем приложении. Вы можете посетить эту ссылку чтобы узнать о поддерживаемых Emojis
Целочисленное деление intdiv()
С помощью функции целочисленного деления — intdiv(), вы получите результат операции деления как целое без применения (int)
Случайные байты — random_bytes()
Функция создает строку случайных байтов. Длина строки задаётся в качестве параметра. Это может быть использовано для создания непредсказуемых значений для куков. Используйте вместе с bin2hex(), чтобы получить шестнадцатеричную строку.
Случайное целое — random_int(int $min, int $max)
Функция создает случайное число с использованием криптографически сильного генератора случайных чисел.
1.0 PHP 7 — ПРОВЕРКА ТИПОВ
Возвращение заявленного типа
Преимущества использования данной функции включают в себя: предотвращение нежелательных возвращаемых значений — это вызовет фатальную ошибку, если тип возвращаемого значения не тот, что вы объявили. Декларирование типа возвращаемого значения не является обязательным в PHP 7. Следующие типы данных могут быть использованы: class name/Interface name, array, callable, bool, float, int, string, self и parentю
Объявление скалярных типов
PHP имеет четыре скалярных типа: Boolean, Integer, Float и String. Скалярные типы используются для идентификации только одного значения. Допустимые типы данных BOOL, INT, float и string. Синтаксис похож на проверку, которые мы рассмотрели выше. Скалярные типы в PHP 7 имеет два режима — слабый (по умолчанию) и строгий (должны быть указаны в явном виде).
Слабый режим — типы данных автоматически преобразуются например, строки преобразуются в целые числа. Минус — вы можете получить неожиданные результаты. В этом режиме, параметры приводятся к указанному типу данных.
Строгий режим — типы данных указываются заранее. Этот режим должен быть включен в файле — вы объявляете «declare(strict_types=1)» в качестве первого оператора в файле PHP. Обратите внимание, что это не влияет на код в подключенных файлах.
2.0 КЛАССЫ И ГЕНЕРАТОРЫ
Анонимные классы
В PHP 5.6 были анонимные функции. В PHP 7, у нас теперь есть анонимные классы. Анонимный класс не имеет имени, но вы можете присвоить его переменной, вернуть его из функции, передать его как аргумент в функцию, расширить класс, реализовать интерфейс и использовать свойства. Однако вы не можете сериализовать анонимный класс.
Типичное использование — когда класс не должен быть документирован, используется только один раз или для модульного тестирования.
Возврат значения из генераторов
Генераторы были включены в PHP 5.5, это был простой способ перебора больших наборов данных, при небольшом потреблении памяти. В PHP 7, теперь вы можете вернуть значение из генератора через $generator->getReturn().
Делегирование генератора
При делегировании генератора, вы можете вызвать генератор внутри другого генератора и задать значения. Генератор внутри другого генератора называется субгенератор.
Нововведения в классе Closure
Вместо того чтобы использовать Closure::bindTo который дублирует замыкание с указанием связанного объекта и области видимости класса, в PHP 7 вы можете использовать Closure::call, который связывает и вызывает замыкание. При использовании Closure::call, нет необходимости указывать имя класса, с объектом которого связывается замыкание — функция автоматически обнаружит его.
Группировка объявлений импорта
Теперь мы можем группировать объявления импорта классов, находящихся в одном пространстве имён, в одной строке. Это поможет нам выровнять декларации неким, наделенным смыслом, образом или же просто сэкономит пару байт вашего кода.
3.0 ОБРАБОТКА ОШИБОК
Перехват фатальных ошибок
PHP 7 изменяет то, как PHP сообщает о большинстве ошибок. Вместо использования традиционного механизма отчетности об ошибках, используемого PHP 5, большинство ошибок теперь генерируют исключения Error. Если вы запустите код из приведенного ниже примера в предварительной версии PHP 7, блок finally не вызывается, и _destruct() тоже. Если затем запустить его в PHP 7, блок finally будет выполнен, но исключение не перехватывается в блоке catch (Exception $e) — вместо этого оно будет перехвачено в блоке catch (Error $e), потому что фатальные ошибки не являются исключениями Exception, их класс называется Error, также деструктор объекта будет вызван при фатальной ошибке.
Throwable
PHP 7 генерирует большинство фатальных ошибок как исключения, которые могут быть перехвачены в блоке try. Исключения и ошибки принадлежат в PHP 7 разным классам. Классы Exception и Error класс реализуют интерфейс Throwable — то есть они имеют такие методы, как getMessage(), getCode(), getFile(), getLine(), getTrace(), _toString() и т.д., и ведут себя очень похожим образом. Есть три подкласса, расширяющих класс Error:
TypeError — генерируется, если тип данных аргумента функции или возвращённого значения не соответствуют объявленному.
ParseError — срабатывает, когда включаемый файл или PHP код, передаваемый в eval() содержит ошибку синтаксиса.
AssertionError — срабатывает, если попытка использовать assert() терпит неудачу. Чтобы включить генерацию этих ошибок, в вашем конфигурационном файле PHP, установите zend.assertion = 1 и assert.exception = 1.
Для того, чтобы создавать свои собственные пользовательские ошибки или классы исключений, необходимо расширить класс Error или Exception — вы не можете реализовать интерфейс Throwable напрямую. Throwable может быть расширен, чтобы добавить новые методы — тогда вы можете реализовать свой расширенный интерфейс.
Новые зарезервированные слова
PHP 7 имеет новые зарезервированные слова, такие как int, float, bool, string, true, false, null, resource, object, mixed и numeric. В шоке? Я тоже! Псевдонимы, такие как integer, double и boolean не зарезервированы.
Значения по умолчанию в Switch
Существует не то баг, не то фича в предварительной версии PHP 7 — там можно добавлять несколько значений по умолчанию в Switch, но в PHP 7+ это вызовет ошибку компиляции.
4.0 Прочие изменения
Произведено значительное улучшение функций, таких как:
— unserialize(string $str [, array $options ]) — улучшена для предотвращения инъекций PHP-объекта (вы можете прочитать об этом здесь и в PHP-документации здесь).
— json_encode($value) — в предварительной версии PHP 7 если у вас есть числовое значение с плавающей запятой в переменной $value, json_encode($value) удалит дробную часть, если она равна 0, и преобразует её в целое число. В PHP 7+, новая константа JSON_PRESERVE_ZERO_FRACTION позволяет сохранить нулевую дробную часть.
«Наполовину» зарезервированные слова
Такие слова, как abstract, and, case, array, as, break, callable, case, catch, clone, const, continue, declare, default, die, do, echo, else, elseif, enddeclare, endfor, endforeach, endif, endswitch, endwhile, exit, extends, final, finally, for, foreach, function, global, goto, if, implements, include, include_once, instanceof, instedof, interface, list, namespace, list, new, or, parent, print, private, protected, public, require, require_once, return, self, static, switch, throw, trait, try, use, var, while, xor, yield теперь могут быть использованы в качестве констант и имен методов (хотя так не рекомендуется делать) в созданных вами классах в PHP 7+, но срабатывает ошибка синтаксиса при произведении таких действий в предварительной версии PHP 7. Единственное «железно» зарезервированное слово — это «class» — его вы не можете использовать. С помощью этой новой информации в вашем распоряжении, перед тем, как начать новый проект на PHP, убедитесь, что вы используете PHP 7, или же вы можете перенести существующие проекты с PHP 5.6.x на PHP 7.0.X, с помощью этого руководства.