Содержание
- Типизированные свойства PHP 7.4
- Оператор Spread
- Контравариантные параметры и ковариантные возвратыы
- Стрелочные функции
- Слабая ссылка
- Предзагрузка
- Сериализация пользовательских объектов
- Функции, которые устарели
- Почему следует перейти на PHP 7.4
Типизированные свойства PHP 7.4
Версия PHP 7.4 получила массу изменений и дополнений, открывающих новые возможности для разработчиков кода. Основные новшества коснулись синтаксиса языка и производительности. Изменения произошли в следующих блоках: оператор распаковки массивов, перезагрузка кода, типизированные свойств классов, стрелочные функции. Рассмотрим подробнее каждый из них.
Пример:
class Bar { public string $name; public ?int $amount; public Foo $foo; }
Новая версия PHP 7.4 получила типизированные свойства классов с обратной совместимостью. На мой взгляд этого очень не хватало ранее. Типы можно указывать для переменных объявленных как: var, public, private, protected. Будьте внимательны, тип - callable и void не допускаются. Свойствам класса теперь присвоен параметр type hint. Со времен PHP 7 сохраняется направление к более строгой типизации. Строгая типизация делает код более читаемым, увеличивает его надежность и производительность.
Например если у нас есть класс:
class test{ public int $var1; } (new test())->var1='string';
Приведет к ошибке:
Fatal error: Uncaught TypeError: Typed property test::$var1 must be int, string used
Оператор Spread
В предыдущих версиях PHP был доступен синтаксис распаковки аргументов функции, выглядело это вот так:
function test(...$args) { var_dump($args); } test(1, 2, 3);
В PHP 7.4 данный функционал был расширен и преобразован в RFC. Стали доступны такие варианты распаковки:
$arr = [...$args];
или даже:
$parts = ['black', 'white']; $fruits = ['red', 'yellow', ...$parts, 'green'];
В сравнении с array_merge
такой синтаксис будет быстрей. Связанно это с тем, что array_merge является функцией, а три точки это часть конструкции языка. Кроме этого для постоянных массивов компиляция выполняется быстрей. У Spread есть еще одно преимущество — array_merge работает только с массивами, а Spread может использоваться так же и с объектами. Array_merge - остался в прошлом. В старых версиях для распаковки массива необходимо было указать три точки перед аргументом.
Еще один пример распаковки:
function test(){ return [1,2,3] } $data=[0,...test(),4,5];
В результате получим массив
[0,1,2,3,4,5]
Контравариантные параметры и ковариантные возвраты
В PHP 7.4 реализована возможность ковариации и контравариантность для всех типов возвращаемых данных и параметров. Ковариантность - если есть изменения порядка от общего к конкретному. Контравариантность - упорядочивание от специфических к общему, то есть наоборот. Инвариантность - применяется при ограничении подтипов. До новой версии в основном применялись инвариантные типы. Если простыми словами, ранее супер класс ограничивал тип его наследников, то теперь подклассы могут расширять или сужать его.
Например:
interface storage{ get(int $id): object; } class userStorage: implements storage { public function get(int $id): User{} }
Стрелочные функции
Анонимные функции в PHP считаются достаточно громоздкими, особенно это касается случаев когда функция состоит всего из одной строки. Поэтому PHP сообщество позаимствовало стрелочные функции (их так же называют короткие замыкания) из JavaScript. Основная цель нововведения - очистить PHP 7.4 от мусора, улучшить читаемость кода и максимально его оптимизировать. Стрелочные функции - сокращенные записи, определяющиеся по значению функции, имеющие неявную привязку к родительской области видимости. Стрелочные функции могут содержать только одну строку, являющаяся оператором возврата значения.
Вот как выглядел старый вариант кода:
function cube($n){ return ($n * $n * $n); } $a = [1, 2, 3, 4, 5]; $b = array_map('cube', $a); print_r($b);
Новый вариант:
array_map(function (User $user) {return $user->id;}, $users) array_map(fn(User $user) => $user->id, $users)
Как видим - он гараздо лучше читается. Еще одним отличием коротких замыканий от анонимных функций является область видимости. Раньше, для того чтоб работать с переменными из родительской области видимости, необходимо было использовать параметр use. Выглядело это Вот так:
$a=0; function() use($a){}
Стрелочные функции неявно имеют доступ к родительской области видимости по значению. Функция $this применяется также, как в обычных анонимных функциях. Оператор объединения с null Еще одно нововведение коснулось оператора присвоения
null. "??"
Теперь можно сразу использовать присвоение. Старый код:
$data['date'] = $data['date'] ?? new DateTime();
Новый вариант:
$data['date'] ??= new DateTime();
Он короче и не требует повторение ненужного синтаксиса. При этом важно помнить, если значения параметра справа не существенно или имеет значения null, ему присваивается значение правого.
Слабая ссылка
В PHP 7.4 появился новый класс WeakReference, позволяющий сохранить ссылку, которая не будет препятствовать уничтожению объекта. Подобные ссылки используются для кэш-подобных структур.
Пример:
$object = new stdClass; $weakRef = WeakReference::create($object); var_dump($weakRef->get()); unset($object); var_dump($weakRef->get());
В результате первый var_dump вернет объект stdClass, а втрой null;
Предзагрузка (preload)
Новый способ оптимизации кода от Дмитрия Строганова, способный значительно увеличить производительность. Представьте себе, что каждый раз при обращении к странице Вашего сайта, происходит загрузка и инициалиазация огромного количества стандартных библиотек и функций Вашего проекта. К примеру для стандартного symfony проекта эта цифра может достигать 100 файлов. На это затрачивается до 20% времени работы скрипта. Preload решает эту проблему. При пмощи директивы opcache.preload в php.ini можно указать загрузочный скрипт, который произведет инициализацию. Перед первым запуском кода, загружается набор PHP файлов во временную память, эти файлы будут доступны для всех следующих запросов, обслуживаемых сервером. Таким образом производительность существенно повысится. Ко всем классам и функциям можно получить доступ также, как к внутренним объектам.
Но есть и обратная сторона медали - загруженные файлы остаются в кэше без изменений, даже если Вы измените файлы на сервере. Чтоб применить изменения нужно перезапустить Apache и php-fpm. Кроме этого, код должен быть написан очень грамотно, ведь изменение состояния любого объекта в общей памяти повлияет на работу всех дальнейших скриптов. Однако прирост в производительности скриптов того стоит. В дальнейшем мы посвятим отдельную статью работе с Preload.
Сериализация пользовательских объектов
Новинка касается механизма настраиваемой сериализации объектов с помощью магических методов
__unserialize() и __serialize().
Последний умеет возвращать массив с перечнем всех состояний указанного объекта. Второй занимается восстановлением первоначального состояния из указанного массива. Нововведение пришло на смену уже устаревшему интерфейсу "Serializable" и методам __sleap() и __wakeup()
Функции, которые устарели
Операторы минус, плюс и точка - имеют одинаковый приоритет и является ассоциативными. Изменения касаются оператора точки. Ей будет присвоен более низкий приоритет, чем оператору сложения и вычитания. Пока что в версии PHP 7.4 выдается только сообщение об устаревании метода использования операторов минус, плюс и точки без скобок. В PHP 8 уже будут добавлены изменения приоритета.
Почему следует перейти на PHP 7.4
Производительность системы выше на 200% по сравнению с использованием старых версий, например, PHP 5.6. Если сравнивать с PHP 5.2 - 400%. Новая версия задействует меньше памяти и способна обрабатывать в три раза больше запросов в сравнении с PHP 7.3.
Дата: 09.12.2019 Автор: Евгений
|
|
Авторам статті важлива Ваша думка. Будемо раді його обговорити з Вами:
comments powered by Disqus