Скидки до 28% + 2-ая профессия бесплатно и подарки на 50 000₽

Главная | Все статьи | Код

Новые возможности PHP 7.4: стрелочные функции, распаковка в массивах, типизированные свойства

Время чтения статьи ~6 минут 12
Новые возможности PHP 7.4: стрелочные функции, распаковка в массивах, типизир... главное изображение

В конце 2019 года вышла новая версия PHP. В этой статье пойдёт речь о возможностях PHP 7.4.

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. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.

Аватар пользователя Дмитрий Дементий
Дмитрий Дементий 17 января 2020
12
Похожие статьи
Рекомендуемые программы
профессия
Верстка на HTML5 и CSS3, Программирование на JavaScript в браузере, разработка клиентских приложений используя React
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Тестирование веб-приложений, чек-листы и тест-кейсы, этапы тестирования, DevTools, Postman, SQL, Git, HTTP/HTTPS, API
4 месяца
с нуля
Старт 26 декабря
профессия
Программирование на Java, Разработка веб-приложений и микросервисов используя Spring Boot, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Google таблицы, SQL, Python, Superset, Tableau, Pandas, визуализация данных, Anaconda, Jupyter Notebook, A/B-тесты, ROI
9 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на PHP, Разработка веб-приложений и сервисов используя Laravel, проектирование и реализация REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на Ruby, Разработка веб-приложений и сервисов используя Rails, проектирование и реализация REST API
5 месяцев
c опытом
Старт 26 декабря
профессия
Программирование на JavaScript в браузере и на сервере (Node.js), разработка бекендов на Fastify и фронтенда на React
16 месяцев
с нуля
Старт 26 декабря
профессия
Программирование на JavaScript, разработка веб-приложений, bff и сервисов используя Fastify, проектирование REST API
10 месяцев
с нуля
Старт 26 декабря
профессия
новый
Git, JavaScript, Playwright, бэкенд-тесты, юнит-тесты, API-тесты, UI-тесты, Github Actions, HTTP/HTTPS, API, Docker, SQL
8 месяцев
c опытом
Старт 26 декабря