• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Гостевая статья Что нового в PHP 8

Ожидается, что новая основная версия PHP 8 будет выпущена к концу 2020 года. Сейчас она находится в очень активной разработке, поэтому в предстоящие месяцы ситуация может сильно измениться.

В этом посте актуальный список того, что ожидается: новые функции, улучшения производительности и критические изменения. Поскольку PHP 8 является новой основной версией, существует большая вероятность взлома вашего кода. Однако если вы были в курсе последних выпусков, обновление не должно быть слишком сложным, поскольку большинство критических изменений ранее не использовались в версиях 7. *.
В PHP 8 также есть несколько приятных новых функций, таких как JIT-компилятор и типы объединения; и это еще не все!
Помните, что PHP 8 все еще находится в активной разработке.

Union types
Учитывая динамически типизированную природу PHP, существует множество случаев, когда типы объединения могут быть полезны. Типы объединения представляют собой набор из двух или более типов, которые указывают, что может использоваться любой из них.
public function foo(Foo|Bar $input): int|float;
Обратите внимание, что void никогда не может быть частью типа объединения, так как он указывает «вообще никакого возвращаемого значения». Кроме того, обнуляемые союзы могут быть записаны с использованием | null или с использованием существующих? обозначения:
Код:
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;

JIT
JIT - just in time - компилятор обещает значительные улучшения производительности, хотя и не всегда в контексте веб-запросов. На данный момент не было сделано никаких точных ориентиров, но они обязательно придут.

Static return type
Хотя уже можно было возвращать self, static не был допустимым типом возврата до PHP 8. Учитывая динамически типизированный характер PHP, эта функция будет полезна для многих разработчиков.
Код:
class Foo
{
    public function test(): static
    {
        return new static();
    }
}

Weak maps
Построенный на RFC слабых ссылок, который был добавлен в PHP 7.4, в PHP 8 добавлена реализация WeakMap. WeakMaps содержат ссылки на объекты, которые не препятствуют сборке мусора этими объектами.

Возьмите пример ORM, они часто реализуют кэши, которые содержат ссылки на классы сущностей, чтобы улучшить производительность отношений между сущностями. Эти объекты сущности нельзя собирать, пока кеш имеет ссылку на них, даже если кеш является единственной ссылкой на них.

Если этот слой кэширования использует слабые ссылки и карты вместо этого, PHP будет собирать эти объекты мусором, когда ничто больше не ссылается на них. Особенно в случае ORM, которые могут управлять несколькими сотнями, если не тысячами объектов в запросе; слабые карты могут предложить лучший, более дружественный к ресурсам способ работы с этими объектами.

Вот как выглядят слабые карты, пример из RFC:
Код:
class Foo
{
    private WeakMap $cache;

    public function getSomethingWithCaching(object $obj): object
    {
        return $this->cache[$obj]
           ??= $this->computeSomethingExpensive($obj);
    }
}

::class on objects
Построенный на RFC слабых ссылок, который был добавлен в PHP 7.4, в PHP 8 добавлена реализация WeakMap. WeakMaps содержат ссылки на объекты, которые не препятствуют сборке мусора этими объектами.
Небольшая, но полезная новая функция: теперь можно использовать :: class для объектов вместо того, чтобы использовать get_class () для них. Он работает так же, как get_class ().
Код:
$foo = new Foo();

var_dump($foo::class);

Create DateTime objects from interface
Вы уже можете создать объект DateTime из объекта DateTimeImmutable, используя DateTime :: createFromImmutable ($ immutableDateTime), но наоборот было сложно. Добавив DateTime :: createFromInterface () и DatetimeImmutable :: createFromInterface (), теперь есть обобщенный способ преобразования объектов DateTime и DateTimeImmutable друг в друга.
Код:
DateTime::createFromInterface(DateTimeInterface $other);

DateTimeImmutable::createFromInterface(DateTimeInterface $other);

fdiv function
Новая функция fdiv делает нечто похожее на функции fmod и intdiv, что позволяет делить на 0. Вместо ошибок вы получите INF, -INF или NAN, в зависимости от случая.

Type annotations for internal functions
Многие люди добавили правильные аннотации типов для всех внутренних функций. Это была давняя проблема, и, наконец, ее можно было решить со всеми изменениями, внесенными в PHP в предыдущих версиях. Это означает, что внутренние функции и методы будут иметь полную информацию о типе в отражении.

Variable syntax tweaks
Из RFC: «Унифицированный синтаксис переменной RFC устранил ряд несоответствий в синтаксисе переменной PHP. Этот RFC намеревается рассмотреть небольшую кучу случаев, которые были упущены из виду».

Breaking changes
Как упоминалось ранее: это серьезное обновление и, следовательно, будут серьезные изменения. Лучшее, что можно сделать, это взглянуть на полный список критических изменений в документе ОБНОВЛЕНИЕ.
Многие из этих критических изменений устарели в предыдущих версиях 7. *, поэтому, если вы были в курсе последних лет, не так уж сложно перейти на PHP 8.

Consistent type errors
Пользовательские функции в PHP уже будут выдавать TypeErrors, но внутренние функции этого не сделали, они скорее выдавали предупреждения и возвращали null. Начиная с PHP 8 поведение внутренних функций стало согласованным.

Reclassified engine warnings
Множество ошибок, которые ранее вызывали только предупреждения или уведомления, были преобразованы в правильные ошибки. Следующие предупреждения были изменены.
  • Неопределенная переменная: ошибка вместо уведомления
  • Неопределенный индекс массива: предупреждение вместо уведомления
  • Деление на ноль: исключение DivisionByZeroError вместо предупреждения
  • Попытка увеличить / уменьшить свойство "% s" необъекта: ошибка вместо предупреждения
  • Попытка изменить свойство "% s" необъекта: ошибка вместо предупреждения
  • Попытка назначить свойство "% s" необъекта: ошибка вместо предупреждения
  • Создание объекта по умолчанию из пустого значения: ошибка вместо предупреждения
  • Попытка получить свойство "% s" необъекта: предупреждение вместо уведомления
  • Неопределенное свойство:% s :: $% s: предупреждение вместо уведомления
  • Невозможно добавить элемент в массив, так как следующий элемент уже занят: ошибка вместо предупреждения
  • Невозможно сбросить смещение в переменной, не являющейся массивом: ошибка вместо предупреждения
  • Нельзя использовать скалярное значение в качестве массива: ошибка вместо предупреждения
  • Только массивы и Traversables могут быть распакованы: исключение TypeError вместо предупреждения
  • Указан неверный аргумент для foreach (): исключение TypeError вместо предупреждения
  • Недопустимый тип смещения: исключение TypeError вместо предупреждения
  • Недопустимый тип смещения в isset или пустой: исключение TypeError вместо предупреждения
  • Недопустимый тип смещения в unset: исключение TypeError вместо предупреждения
  • Преобразование массива в строку: предупреждение вместо уведомления
  • Идентификатор ресурса #% d, используемый в качестве смещения, приведение к целому числу (% d): предупреждение вместо уведомления
  • Произошло приведение смещения строки: предупреждение вместо уведомления
  • Смещение неинициализированной строки:% d: предупреждение вместо уведомления
  • Невозможно назначить пустую строку для смещения строки: исключение ошибки вместо предупреждения
Default error reporting level
Теперь это E_ALL вместо всего, кроме E_NOTICE и E_DEPRECATED. Это означает, что может появиться много ошибок, которые ранее молча игнорировались, хотя, возможно, уже существовали до PHP 8.

The @ operator no longer silences fatal errors
Вполне возможно, что это изменение может выявить ошибки, которые снова были скрыты до PHP 8. Убедитесь, что display_errors = Off на ваших производственных серверах!

Concatenation precedence
Хотя это изменение уже устарело в PHP 7.4, теперь это изменение вступает в силу. Если бы вы написали что-то вроде этого:
echo "sum: " . $a + $b;
PHP ранее интерпретировал бы это так:
echo ("sum: " . $a) + $b;
PHP 8 сделает так, чтобы он интерпретировался так:
echo "sum: " . ($a + $b);

Reflection method signature changes
Три сигнатуры методов классов отражения были изменены:
Код:
ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);
Теперь стали:
Код:
ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);
В руководстве по обновлению указано, что если вы расширяете эти классы и по-прежнему хотите поддерживать как PHP 7, так и PHP 8, допускаются следующие подписи:
Код:
ReflectionClass::newInstance($arg = null, ...$args);
ReflectionFunction::invoke($arg = null, ...$args);
ReflectionMethod::invoke($object, $arg = null, ...$args);

Several small deprecations
Во время разработки PHP 7. * было добавлено несколько устаревших версий, которые теперь завершены в PHP 8.
  • Deprecations in PHP 7.2
  • Deprecations in PHP 7.3
  • Deprecations in PHP 7.4
Источник:
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!