PHP 8: что нового

PHP 8 выйдет 3 декабря 2020 года. Не следует ждать PHP 7.5, стоит сразу приготовиться к новому мажорному релизу. Сейчас PHP 8 находится в очень активной разработке, и здесь постараемся собрать все изменения и улучшения, которые будут.

Помимо существенных изменений, PHP 8 содержит несколько приятных новых функций, таких как JIT-компилятор, типы объединения, атрибуты и многое другое.

Многие изменения в PHP 8 были объявлены deprecated в предыдущих версиях PHP 7.*, поэтому, если вы всегда на актуальной версии языка — проблем с переходом на PHP 8 быть не должно.

Union Types 2.0

Учитывая тот факт, что PHP это динамически типизированный язык, существует множество случаев, когда объединение типов может быть полезным. Это значит, что может быть использован любой из указаных типов данных:

public function foo(Foo|Bar $input): int|float;

На примере, функция foo может принимать переменную $input, которая должна быть объектом класса Foo или Bar. В тоже время, определено что функция может вернуть число типа int или float.

Обратите внимание, что void никогда не может быть частью типа объединения, так как он указывает что возвращаемого значения нет и не может быть.

Использование ::class на объектах

Небольшая, но полезная новая функция: теперь можно использовать ::class для объектов вместо того, чтобы использовать get_class() для них. Работает так же, как get_class().

$foo = new Foo();

var_dump($foo::class);

Создание DateTime объектов из интерфейса

Сейчас можно создать объект DateTime из объекта DateTimeImmutable, используя DateTime::createFromImmutable ($ immutableDateTime). Теперь можно превращать объкты DateTime и DateTimeImmutable друг в друга.

Для этого добавлены DateTime::createFromInterface() и DatetimeImmutable::createFromInterface().

Унифицированный синтаксис переменных

PHP поддерживает 4 типа обращения к переменным:

  • Array: $foo[$bar]$foo{$bar}
  • Object: $foo->bar$foo->bar()
  • Static: Foo::$barFoo::bar()Foo::BAR
  • Call: foo()

Принятый RFC устранил ряд несоответствий в синтаксисе переменных PHP.

Приоритет в конкатенации

Хотя это уже устарело в PHP 7.4, теперь это изменение вступает в силу. Раньше можно было написать что-то подобное на:

echo "sum: " . $a + $b;

PHP интерпретировал это как («sum: » . $a) + $b. Теперь же, PHP 8 будет это интерпретировать как:

echo "sum: " . ($a + $b);

Более строгие проверки типов для арифметических и побитовых операторов

До PHP 8 можно было применять арифметические или побитовые операторы к массивам, ресурсам или объектам. В PHP 8 это не возможно и вызовет ошибку TypeError:

[] % [42];
$object + 4;

Улучшения в функциях PHP

ФункцияИзменение
token_get_all()Добавлен класс PhpToken, который содержит метод PhpToken::getAll(). Эта реализация работает с объектами вместо простых значений. Он потребляет меньше памяти и с этим легче работать.

Новые функции в PHP 8

ФункцияНазначение
get_debug_type()возвращает тип переменной. В отличии от gettype() возвращает более полезный вывод для массивов, строк, анонимных классов и объектов.
fdiv()похожа на fmod() и intdiv(), что позволяет делить на 0. Вместо ошибок получаем INF, -INF или NAN, в зависимости от случая. Согласовано с семантикой IEEE-754.
str_starts_with()проверяет, начинается ли строка с определенной строки. Возвращает TRUE / FALSE.
str_ends_with()проверяет, заканчивается ли строка с определенной строки. Возвращает TRUE / FALSE.
str_contains()Ура! Теперь не нужно использовать strpos() чтобы прверить, что строка содержит другую строку.

Stringable interface

Интерфейс Stringable может быть использован для ввода подсказки всего, что является строкой или реализует __toString (). Кроме того, всякий раз, когда класс реализован__toString (), интерфейс Stringable ьудет автоматически реализован.

class Test {
    public function __toString() {
        return "foo";
    }
}

var_dump(new Test instanceof Stringable);
var_dump((new ReflectionClass(Test::class))->getInterfaceNames());

class Test2 extends Test {
    public function __toString() {
        return "bar";
    }
}

var_dump(new Test2 instanceof Stringable);
var_dump((new ReflectionClass(Test2::class))->getInterfaceNames());

/* Результат */
bool(true)
array(1) {
  [0]=> string(10) "Stringable"
}
bool(true)
array(1) {
  [0]=> string(10) "Stringable"
}

JIT-компилятор в PHP 8

JIT (Just In Time) — это динамическая компиляция байт кода в машинный. Наличие JIT компилятора в PHP обещает значительные улучшения производительности в работе программы. Исходя из официального RFC, PHP JIT будет реализован как почти независимая часть OPcache. Его можно будет включать / выключать во время компиляции или выполнения скрипта. Эксперементально, функция доступна в PHP 7.4, но она отключена по умолчанию.

Другие улучшения в PHP 8

Небольшие изменения:

  • режим ошибок в PDO. Текущий режим ошибок по умолчанию для PDO — беззвучный. Это означает, что при возникновении ошибки SQL никакие ошибки, исключения или предупреждения не генерируются, если не реализована своя явная обработка ошибок.
  • уровень сообщений об ошибках по умолчанию. По умолчанию теперь установлен E_ALL. Раньше было все кроме E_NOTICE иE_DEPRECATED.
  • Оператор @ больше не скрывает Fatal Error.
  • несоответствие типов агрументов в пользовательских функциях вызывает TypeError, в то время как стандартные функции возвращают предупреждение или null. Пример проблемы:
var_dump(DateTime::createFromFormat(new stdClass, "foobar"));
// Warning: DateTime::createFromFormat() expects parameter 1 to be string, object given
// bool(false)
 
var_dump(DateTime::createFromFormat("foobar", "foobar", new stdClass));
// TypeError: Argument 3 passed to DateTime::createFromFormat() must be an instance of DateTimeZone or null, instance of stdClass given

Теперь такой ситуации не должно быть. Теперь будет только TypeError.

Изменения в ошибках и их интерпретации на уровне ядра PHP 8

Довольно интересное изменение, которое сделает ошибки, исключения и предупреждения в ядре PHP более логичными. Что изменилось:

  • деление на ноль (DivisionByZeroError) теперь выбрасывает исключение вместо предупреждения,
  • неопределенный индекс массива (Undefined array index): предупреждение вместо уведомления,
  • неопределенная переменная (Undefined variable): ошибка вместо уведомления,
  • преобразование массива в строку (Array to string conversion): предупреждение вместо уведомления.

Это не полный список. Он намного больше и его можно посмотреть в принятом FRC: https://wiki.php.net/rfc/engine_warnings.

Default image
Агентство интернет-маркетинга
Агенство эффективного интернет-маркетинга предлагает услуги по созданию, оптимизации и продвижении вашего ресурса в интернете.
guest
0 Комментарий
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x