В конце 2019 года вышла новая версия PHP. В этой статье пойдёт речь о возможностях PHP 7.4.
- Новая версия делает PHP более выразительным
- Устаревшие конструкции
- Повышение производительности
- Ковариантные возвраты и контравариантные параметры
- О перспективах
PHP — один из самых востребованных языков программирования. Он широко используется в веб-разработке: на PHP написаны популярные CMS, в том числе WordPress, Joomla!, Drupal. На этом языке созданы фреймворки Laravel, Yii2 и Symfony, которые активно используют веб-разработчики.
Давайте посмотрим, какие инструменты появились у разработчиков после выхода PHP 7.4.
Новая версия делает PHP более выразительным
Версия PHP 7.3 принесла в язык новый синтаксис и производительность. А PHP 7.4 делает код более удобным, читабельным и простым в поддержке. Благодаря этому язык становится быстрее и надёжнее. Ниже описаны основные нововведения версии 7.4.
Стрелочные функции
PHP-программисты давно ждали появления стрелочных функций, похожих на стрелочные функции в JavaScript. Такой синтаксис проще использовать. Однако функции массивов в PHP, известные как короткие замыкания, отличаются от стрелочных функций в JS.
В PHP 7.4 появляется ключевое слово fn
. Короткие замыкания могут содержать только одно выражение без ключевого слова return
. Стрелочные функции в PHP — не такой мощный инструмент, как их «тёзки» из JavaScript. Но в некоторых ситуациях они становятся оптимальным инструментом.
// old way
$ids = array_map(function ($post) {
return $post->id;
}, $posts);
// new way
$ids = array_map(fn($post) => $post->id, $posts);
Типизированные свойства PHP
Приведение типов появилось в PHP 5.0. В более поздних версиях эта функциональность развивалась. В версии 7.0 появились типы возвращаемых значений. В PHP 7.4 ввели объявление типов для свойств классов.
Типизированные свойства работают внутри классов и требуют модификаторов доступа. Чтобы лучше понять концепцию, рассмотрим пример.
class Event {
public int $id;
public string $title;
}
В коде выше значением свойства $id
может быть только число, а значением $title
— строка. Если вы попытаетесь использовать другие типы данных, получите фатальную ошибку.
Распаковка внутри массивов
Распаковка аргументов появилась в PHP 5.6. А начиная с версии 7.4 можно пользоваться распаковкой внутри массивов. Это должно быть быстрее, чем array_merge()
благодаря спред-оператору.
В коде ниже видно, как работает распаковка внутри массива.
$colors_new = ['green', 'grey'];
$colors_old = ['red', 'orange', ...$colors_new, 'blue'];
// ['red', 'orange', 'green', 'grey', 'blue'];
Присваивающий оператор объединения с null
Это нововведение упрощает код в некоторых ситуациях. Фактически это быстрый способ объединить проверку isset()
с тернарным оператором. В примере ниже видно, как можно обратиться к значению ключа id
в ассоциативном массиве $product
. Если значение ключа установлено, то вновь устанавливается то же значение. Если оно не установлено, присваивается значение справа. Показаны примеры кода на PHP 7.0 и 7.4. Видно, что последняя версия лаконичнее.
// PHP 7.0
$product['id'] = $product['id'] ?? 0;
// PHP 7.4
$product['id'] ??= 0;
Слабые ссылки
Эта возможность позволяет разработчикам сохранять ссылки на объекты. Сохранение ссылки не исключает уничтожение объекта. С помощью слабых ссылок (weak references) создаётся подобие кэшированных структур. Пример:
$object = new stdClass;
$weakRef = WeakReference::create($object);
var_dump($weakRef->get()); // object(stdClass)#1
unset($object);
var_dump($weakRef->get()); // NULL
Устаревшие конструкции
С выходом PHP 7.4 часть возможностей языка переходит в категорию устаревших (deprecations). Язык перестанет их поддерживать.
Вложенный тернарный оператор без скобок
Вложенные тернарные операторы лучше не использовать. В таких конструкциях легко ошибиться. Но если вы всё-таки хотите применить вложенный тернарный оператор, используйте его со скобками. Начиная с версии PHP 7.4 вложенные тернарные операторы без скобок считаются устаревшими.
// Not OK (deprecated)
$value = $a ? $b : $c ? $d : $e;
// Ok
$value = ( $a ? $b : $c ) ? $d : $e;
// Ok
$value = $a ? $b : ( $c ? $d : $e );
Использование array_key_exists()
с объектами
Не используйте array_key_exists()
с объектами, так как объекты — не массивы. Вместо этого лучше использовать функцию property_exists()
или isset ()
.
// Not OK (deprecated)
if (array_key_exists($property, $object)) {}
// Ok
if (property_exists($property, $object)) {}
// Ok
if (isset($object->$property)) {}
Обращение к индексу массива или строки с помощью фигурных скобок
Использование фигурных скобок для обращения к индексу массива или строки в реальном коде встречается редко. А начиная с версии PHP 7.4 такой код считается устаревшим.
// Not OK (deprecated)
$value = $a{$key};
// Ok
$value = $a[$key];
Короткие открытые теги
В PHP использовались разные альтернативы открытым тегам <?php … ?>
для обозначения начала PHP-кода. Большая часть этих альтернатив была удалена из языка после выхода версии 7.0. Однако некоторые из коротких открытых тегов PHP остались.
Примеры:
// не будет работать
<?php/*blah*/ echo "a"?>
// будет работать
<?php /*php followed by space*/ echo "a"?>
// будет работать
<?php
/*php followed by end-of-line*/ echo "a"?>
Повышение производительности
Главная мотивация перейти на PHP 7.4 — повышение производительности. В версии 7.4 используется предварительная загрузка. Она реализована с помощью расширения Opcache. Это расширение сохраняет в общей памяти предварительно скомпилированный байткод. Благодаря этому не нужно загружать скрипты при каждом запросе.
Opcache работает с опкодом — упрощённым или низкоуровневым представлением PHP-кода. Расширение предварительно компилирует написанный разработчиком код в опкод и загружает в память. Так работает предварительная загрузка.
Этот механизм работает быстрее альтернативы: загрузки файлов при каждом запросе. В конечном итоге благодаря предварительной загрузке растёт производительность PHP 7.4.
Ковариантные возвраты и контравариантные параметры
До выхода версии 7.4 в PHP использовались преимущественно инвариантные параметры и возвращаемые типы. В новой версии вводится ковариантность и контравариантность для типов возвращаемых данных и параметров.
Есть такие типы параметров:
- Инвариантные. Используются, если тип супертипа ограничивает тип подтипа.
- Ковариантные. Применяются, если порядок типов сохраняется, то есть типы упорядочены от более специфичных к более общим.
- Контравариантные. Используются при изменении порядка от более общих к более специфичным типам.
Код ниже показывает ковариантный и контравариантный типы возврата.
Ковариантный:
interface Factory {
function make(): object;
}
class UserFactory implements Factory {
function make(): User;
}
Контравариантный:
interface Concatable {
function concat(Iterator $input);
}
class Collection implements Concatable {
function concat(iterable $input) {/* ... */}
}
О перспективах
В PHP 7.4 появилось не слишком много новых возможностей, поэтому не все разработчики верят в сильное повышение производительности. В сообществе PHP-программистов идут разговоры о версии 8.0, которая принесёт в язык программирования большие нововведения и серьёзно повысит производительность.Тем не менее точная дата релиза PHP 8.0 пока не объявлена.
Адаптированный перевод статьи A Closer Look at PHP’s Latest Version 7.4 by Ruchika Singh Aggarwal. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.