- Заміна тернарного оператора
- Групове оголошення класів, констант і функцій
- Декларація типів і значень
- Обробка помилок і виключень
- Решта нововведення одним списком
- додаткове чтиво
Два місяці тому я перейшов на PHP7 і в цьому пості хочу поділитися нововведеннями, які припали до вподоби мені найбільше. По-перше, перехід на нову гілку PHP обумовлений приростом продуктивності і зменшенням споживаних ресурсів, т. Е. Великі сайти з PHP7 можуть в два рази знизити витрати на хостинг і швидше генерувати веб-сторінку кінцевому користувачеві. Тут виграють відразу і власники сайтів, і їх відвідувачі.
це порівняння швидкості між версіями 5.6 і 7.0 на різних платформах. Zend Framework дає приріст швидкості на 133%, а WordPress - 129%. Таке поліпшення PHP має позитивні наслідки для бізнесу.
У минулому році Badoo, WordPress.com, Tumblr і багато інших гіганти перейшли на PHP7. Так, наприклад, компанії Badoo за рахунок зниження CPU в два рази і зменшення споживання пам'яті в 8 разів вдалося заощадити 1 млн доларів . Сайт WordPress.com також повністю переведений на PHP7, де приріст продуктивності дійсно помітний:
Швидкодія в нових версіях стало найкрутішим і найбільш обговорюваним нововведенням. Тепер не потрібно морочитися з оптимізації якихось ділянок коду, а відразу писати зрозумілий і підтримуваний код. По-друге, в PHP 7.0 і 7.1 введено велику кількість поліпшень на рівні синтаксису і функціональності. Далі на прикладах я покажу, що мені сподобалося в нових версіях і як ці нововведення поміняють мову PHP в майбутньому на рівні коду.
Заміна тернарного оператора
На заміну тернарного оператора прийшов «оператор об'єднання з null» або «null-коалесцентний оператор». Через два знака питання (??) можна вказати ланцюжок значень в один рядок і буде вибрано перше значення, яке не дорівнює null. Раніше цей підхід застосовувався разом з функцією isset (). Зараз можна вказати навіть не існуючі змінні і не мучаться c великий вкладеністю як з тернарного оператором.
<? Php // PHP 5.6 $ test = isset ($ foo)? $ Foo: null; // PHP 7 + $ test = $ foo ?? null; / * ... * / // PHP 5.6 $ test = isset ($ foo)? $ Foo: (isset ($ bar)? $ Bar: null); // PHP 7 + $ test = $ foo ?? $ Bar ?? null; / * ... * / // PHP 7 + someFunction ($ unknownVariable ?? 'default');
Оператор об'єднання з null
Тернарний оператор і оператор null-coalescing
Групове оголошення класів, констант і функцій
Починаючи з версії 7.0 з'явилася можливість групувати оголошення імпорту класів, функцій і констант, що знаходяться в одному просторі імен, в одному рядку за допомогою оператора use. Це нововведення на рівні синтаксичного цукру, яке може наділити оголошення імен якихось компонентів певної логікою.
<? Php // PHP 5.6 use App \ Bundle \ Foo; use App \ Bundle \ Bar; use App \ Bundle \ Baz as B; // PHP 7 + use App \ Bundle \ {Foo, Bar, Baz as B}; // або use App \ Bundle \ {Foo, Bar, Baz as B}; / * ... * / // PHP 5.6 use const app \ namespace \ ru_RU; use const app \ namespace \ en_US; use function app \ namespace \ firstFunc; use function app \ namespace \ secondFunc; // PHP 7 + use const app \ namespace \ {ru_RU, en_US}; use function app \ namespace \ {firstFunc, secondFunc};
Групові декларації use
Декларація типів і значень
Це найпотужніше нововведення для ООП. Тепер при оголошенні методу для кожної змінної можна вказати свій тип, а також тип даних, який поверне цей метод. У PHP 7.0 доступні наступні типи: array, callable, bool, float, int, string, ім'я класу або інтерфейсу. У версії 7.1 додали ще void і iterable. Тип void можна використовувати тільки в повертаються значеннях функцій, які нічого не повертають. Псевдо-тип iterable використовується в якості значення масиву або об'єкта, що реалізує інтерфейс Traversable .
<? Php class Foo {public static function bar (int $ a, float $ b, string $ c): int {return $ a + $ b + $ c; }} // поверне int (6) var_dump (Foo :: bar ( '1', 2, 3.0));
В наведеному вище прикладі відпрацювала принуждающая декларація типів, т. Е. PHP динамічно привів значення до потрібного типу, коли в змінну з оголошеним типом int ми передали string, наприклад. Замість того, щоб згенерувати помилку, все значення змінних і результат функції був перетворений до зазначеного типу на льоту. Це поведінка встановлено за замовчуванням.
Строгу типізацію можна включити, якщо на початку скрипта прописати declare (strict_types = 1). Всі значення повинні повністю відповідати зазначеним типам. В іншому випадку буде згенеровано помилка TypeError. Сувора типізація торкається весь інший код і її потрібно прописувати для кожного скрипта окремо.
<? Php // включили строгу типізацію declare (strict_types = 1); class Foo {public static function bar (int $ a, int $ b): int {return $ a + $ b; }} // поверне помилку TypeError, т. К. // перший аргумент є string, // а повинен int var_dump (Foo :: bar ( '1', 2)); // поверне int (3) var_dump (Foo :: bar (1, 2));
У версії 7.1 з'явилася можливість обнулити повертаються типи. Це розширює список возвращаеммих типів до null. Тепер функція може повернути якийсь явно вказаний тип або null. Досягається така поведінка шляхом додавання префікса у вигляді знака питання до зазначеного типу:
<? Php declare (strict_types = 1); class Foo {public static function bar (? string $ name):? string {return $ name; }} // string (13) "Hello, world!" var_dump (Foo :: bar ( 'Hello, world!')); // NULL var_dump (Foo :: bar (null)); // string (0) "" var_dump (Foo :: bar ( '' ?? null)); // NULL var_dump (Foo :: bar ($ unknownVariable ?? null)); // поверне помилку TypeError var_dump (Foo :: bar (1)); // поверне помилку ArgumentCountError var_dump (Foo :: bar ());
Декларація типів і значень виводить PHP на новий рівень і ці нововведення мені подобаються найбільше, т. К. З боку розробника підвищується читабельність коду; чітка узгодженість вхідних і вихідних даних; програміст може швидше зрозуміти, чого очікувати від функції; легше документувати код; з'являється можливість змінювати типи даних на льоту. Це основна функціональність PHP7, якої не знати вже зараз неприпустимо.
Декларація скалярних типів
Декларація значень, що повертаються
обнуляє типи
Нічого не повертають функції
Псевдо-тип iterable
Обробка помилок і виключень
У PHP 7.0 з'явився новий клас для внутрішніх помилок Error і інтерфейс винятків Throwable . Тепер Error і старий клас Excetion реалізують Throwable (призначені для користувача класи не можуть реалізовувати даний інтерфейс). Exception можна використовувати для вилову винятків, які будуть оброблені та виконання програми продовжиться. Клас Error служить для незворотних винятків і викидається в разі помилки PHP або на рівні помилок розробників.
Більшість помилок рівня E_ERROR або E_RECOVERABLE_ERROR викидатимуть Error, але деякі будуть викидати об'єкти підкласів : ArithmeticError, AssertionError, ParseError, DivisionByZeroError, TypeError і ArgumentCountError (з версії 7.1). Ці підкласи помилок не можуть бути кинуті самостійно, а тільки лише словлени. Ієрархію всіх винятків можна представити у вигляді дерева:
┌Throwable ├──Error │ ├──ArithmeticError │ ├──AssertionError │ ├──DivisionByZeroError │ ├──ParseError │ ├──TypeError │ └──ArgumentCountError └──Exception ├──ErrorException ├──LogicException │ ├ ──BadFunctionCallException │ │ └──BadMethodCallException │ ├──DomainException │ ├──InvalidArgumentException │ ├──LengthException │ └──OutOfRangeException └──RuntimeException ├──OutOfBoundsException ├──OverflowException ├──RangeException ├──UnderflowException └ ──UnexpectedValueException
Починаючи з версії 7.1 з'явилася можливість в блоці catch обробляти відразу кілька винятків, перераховуючи їх через символ вертикальної риски. Може бути корисно для обробки однакових за логікою помилок або призначених для користувача винятків.
<? Php try {/ * * код програми * /} catch (ParseError | TypeError | ArgumentCountError $ e) {/ * * ловимо три види помилок PHP в одному блоці * /} catch (AppException | UserException $ e) {/ * * ловимо призначені для користувача виключення * /} catch (Exception $ e) {/ * * ловимо інші винятки * /} catch (Throwable $ t) {/ * * ловимо і логіруем всі помилки і виключення * /}
На місце фатальних помилок прийшли виключення, які можуть бути оброблені і дозволяють коректно завершити програму в разі якихось косяків. Це додає гнучкості PHP-додатку.
зумовлені виключення
Зміни в обробці помилок і виключень
Обробка декількох винятків в одному блоці catch
Решта нововведення одним списком
Нововведення в PHP7 + це лише початок великого переходу на новий рівень мови. З кожним релізом додатки будуть ставати швидше і безпечніше. На версії 7.0 і 7.1 потрібно відреагувати вже сьогодні і будь в курсі нових тенденцій PHP, щоб не випадати з сфери. Нижче наводжу одним списком інші нововведення:
7.0 Оператор spaceship (космічний корабель) ↩
7.0 Завдання констант масивів за допомогою define () ↩
7.0 З'явилися анонімні класи ↩
7.0 Синтаксис кодування Unicode ↩
7.0 долучення метод в замикання Closure :: call () ↩
7.0 unserialize () з фільтрацією ↩
7.0 Новий клас IntlChar ↩
7.0 Покращена стара функція assert () ↩
7.0 Вираз return в генераторах ↩
7.0 Делегація генератора за допомогою конструкції yield from ↩
7.0 Нова функція intdiv () для цілочисельного ділення ↩
7.0 session_start () приймає масив опцій ↩
7.0 Нова функція preg_replace_callback_array () ↩
7.0 Нові функції random_bytes () і random_int () ↩
7.0 list () може розкривати об'єкти реалізують ArrayAccess ↩
7.0 Звернення до методів і властивостей класу при клонуванні (clone $ foo) -> bar () ↩
7.1 Короткий синтаксис для list () ↩
7.1 Публічні і приватні константи класів ↩
7.1 Підтримка ключів в list () ↩
7.1 Підтримка негативних зсувів для рядків ↩
7.1 Розширено функції openssl_encrypt () і openssl_decrypt () ↩
7.1 Перетворення callable в Closure за допомогою Closure :: fromCallable () ↩
7.1 Нова функція pcntl_async_signals () ↩
7.1 Підтримка Server Push в CURL 7.46 ↩
додаткове чтиво
Міграція з PHP 5.6.x до PHP 7.0.x
Міграція з PHP 7.0.x до PHP 7.1.x
Порівняння швидкості для різних фреймворків в PHP7
Інфографіка: Turbocharging the Web with PHP7
Введення в PHP 7: що додано, що прибрано
PHP 7.1: огляд нових можливостей
Return types і Scalar type в PHP7
Throwable виключення і помилки в PHP7
Test = isset ($ foo)?
Foo: null; // PHP 7 + $ test = $ foo ?
Test = isset ($ foo)?
Foo: (isset ($ bar)?
Bar: null); // PHP 7 + $ test = $ foo ?
Bar ?
UnknownVariable ?
Lt;?
Lt;?