В этом релизе появятся хуки свойств, поддержка HTML5, а также возможность цепочки методов без дополнительных скобок — это действительно важное изменение!
#Хуки свойств (Property Hooks) RFC
Одно из самых значительных изменений в истории современного PHP: возможность определять хуки свойств, что устраняет необходимость в большом количестве шаблонного кода.
class BookViewModel { public function __construct( private array $authors, ) {} public string $credits { get { return implode(', ', array_map( fn (Author $author) => $author->name, $this->authors, )); } } public Author $mainAuthor { set (Author $mainAuthor) { $this->authors[] = $mainAuthor; $this->mainAuthor = $mainAuthor; } get => $this->mainAuthor; } }
Цель хуков свойств заключается в том, чтобы избавиться от большого количества геттеров и сеттеров, позволяя каждому свойству определять свои собственные хуки для получения и установки значения. Хуки являются необязательными, и вы можете добавлять только один из них для конкретного свойства. Например, свойство с одним лишь хуком get
является виртуальным свойством.
Есть еще много чего рассказать о хуках свойств, и я планирую написать отдельный пост об этом в ближайшее время, так что обязательно подпишитесь, если хотите узнать больше. Одна последняя вещь, которую я хотел бы отметить — возможно, то, что меня больше всего радует: хуки свойств можно определять в интерфейсах!
interface HasAuthors { public string $credits { get; } public Author $mainAuthor { get; set; } }
#Создание объектов без скобок (new without parentheses) RFC
Как будто одних хуков свойств было недостаточно, PHP 8.4 предлагает еще одну функцию, которая значительно сократит количество шаблонного кода: теперь вам не нужно оборачивать вызовы new
в скобки для возможности использования цепочек методов. Вместо того чтобы писать так:
$name = (new ReflectionClass($objectOrClass))->getShortName();
Теперь можно делать так:
$name = new ReflectionClass($objectOrClass)->getShortName()
Я не знаю как вы, но я пишу много такого кода, и поэтому очень рад, что наконец-то мы избавляемся от этих лишних скобок. Это работает не только для методов, кстати. Вы также можете использовать цепочки для свойств, статических методов, констант — чего угодно. Подробнее об этой новой функции можно прочитать в специальном посте .
#Асимметричная видимость (Asymmetric Visibility) RFC
Еще одна революционная функция PHP 8.4 — это асимметричная видимость. Асимметричная видимость позволяет классам определять видимость свойств (public, protected или private) в зависимости от контекста чтения или записи. Наиболее распространенный пример асимметричной видимости — это публичные свойства, которые могут быть изменены только внутри класса. Такое свойство будет выглядеть так:
class BookViewModel { public private(set) Author $author; }
Поскольку «публичные свойства, которые могут быть изменены только в приватном контексте», являются наиболее распространенным случаем асимметричной видимости, существует также сокращенная запись:
class BookViewModel { private(set) Author $author; // то же самое, что public private(set) }
Конечно, вы также можете сделать свойства доступными для записи только в защищенном контексте:
class BookViewModel { public protected(set) Author $author; }
И, естественно, этот синтаксис работает и для продвигаемых свойств:
public function __construct( private(set) Author $author; ) {}
#Функция array_find() RFC
В PHP 8.4 добавлена довольно простая новая функция, о которой многие разработчики могли задаться вопросом: «Подождите, разве этого еще не было?». Многие привыкли к сторонним коллекциям, хотя я думаю, что наличие array_find()
нативно в PHP — это довольно удобно.
Название может немного сбивать с толку, потому что эта функция принимает массив и callback, и возвращает первый элемент, для которого callback возвращает true
:
$firstMatch = array_find( $posts, function (Post $post) { return strlen($post->title) > 5; } );
Также есть несколько вариаций этой функции: array_find_key()
, array_any()
и array_all()
. Подробнее о них можно прочитать здесь .
#Устаревание неявных nullable типов
Раньше PHP имел странное поведение, когда типизированная переменная с дефолтным значением null
автоматически становилась nullable:
function save(Book $book = null) {} // Устарело: Неявное указание параметра $book как nullable устарело, // необходимо явно указывать nullable тип
Это поведение теперь устарело и будет удалено в PHP 9. Решение — явно указать nullable:
function save(?Book $book = null) {}
#Новая поддержка HTML5 RFC
PHP 8.4 добавляет класс \Dom\HTMLDocument
, который способен правильно парсить HTML5 код. Старый класс \DOMDocument
все еще доступен для обратной совместимости.
$doc = \Dom\HTMLDocument::createFromString($contents);
Подробнее о новом HTML5 парсере можно прочитать здесь .
#Изменения JIT RFC
PHP 8.4 меняет способ включения JIT. Раньше вам нужно было установить opcache.jit_buffer_size
в 0, чтобы отключить JIT, но теперь вы можете отключить его следующим образом:
opcache.jit=disable opcache.jit_buffer_size=64m
Единственный случай, когда пользователи могут быть затронуты этим изменением, — если они указали opcache.jit_buffer_size
, но не указали opcache.jit
. В этом случае вам нужно будет добавить opcache.jit=tracing
, чтобы снова включить JIT.
Кроме того, были сделаны некоторые улучшения в JIT, которые делают его быстрее в некоторых случаях и используют меньше памяти.
#Ленивые объекты (Lazy Objects) RFC
Наконец, PHP 8.4 добавляет нативную поддержку ленивых объектов, часто используемых фреймворками для создания прокси-объектов.
$initializer = static function (MyClass $proxy): MyClass { return new MyClass(123); }; $reflector = new ReflectionClass(MyClass::class); $object = $reflector->newLazyProxy($initializer);
#exit и die как функции RFC
В PHP exit
(и его псевдоним die
) — это довольно странные вещи: их можно использовать как ключевые слова (exit;
), но также и как функции (exit(0);
). Однако вариант функции на самом деле не был полноценной функцией, а скорее чем-то, что ведет себя как функция, но не полностью:
- не поддерживал именованные аргументы;
- не мог передаваться как callable;
- игнорировал
strict_types
; - не следовал обычным правилам преобразования типов.
С PHP 8.4 exit()
и die()
теперь правильно рассматриваются как функции, и все вышеупомянутые проблемы исправлены. Обратите внимание, что вариант с ключевым словом без скобок, конечно, продолжает работать так же.
#Объектный API для BCMath RFC
Раньше bcmath
поддерживал только функциональный API. С PHP 8.4 вы можете использовать объектно-ориентированный API. Особенно круто в этой функции то, что эти объекты Number
поддерживают перегрузку операторов, и вы можете использовать их непосредственно в вычислениях!
use BCMath\Number; $num = new Number('1'); $num2 = new Number('2'); $result = $num + $num2; $result->value; // '3'
#Атрибут #[Deprecated] RFC
Теперь в PHP есть встроенный атрибут, который можно использовать для пометки методов, функций и классов как устаревших. Раньше вы могли использовать docblock вроде /** @deprecated */
, но PHP ничего с этим не делал. Хотя статические анализаторы и IDE могли интерпретировать эти docblocks, вам нужны были внешние инструменты, чтобы убедиться, что все устаревшие элементы были обнаружены.
Теперь пакеты и фреймворки могут полагаться на встроенный атрибут #[Deprecated]
, который также поддерживает добавление метаданных:
#[Deprecated("используйте newFunction() вместо", since: "tempest/framework:1.1")] function oldFunction() { // … }
#добавления
- Новая функция
request_parse_body()
, которая позволяет парсить RFC1867 (multipart) запросы в HTTP-запросах, отличных от POST. Читать подробнее - Новые статические конструкторы для создания объектов
DateTime
иDateTimeImmutable
из временной метки:DateTime::createFromTimestamp($timestamp)
иDateTimeImmutable::createFromTimestamp($timestamp)
- Две новые функции, связанные с микросекундами в объектах
DateTime
иDateTimeImmutable
:DateTime::getMicrosecond()
иDateTimeImmutable::setMicrosecond($microsecond)
- Теперь есть поддержка драйвер-специфичных подклассов PDO. Читать подробнее
- Новая поддержка драйвер-специфичных SQL-парсеров. Читать подробнее
#Обратно несовместимые изменения
- Константа
E_STRICT
устарела, и соответствующий уровень ошибок удален. Читать подробнее - Некоторые свойства DOM-элементов устарели. Читать подробнее
- Класс GMP теперь является финальным и не может быть расширен. Читать подробнее
- Дополнительные ошибки значений в MBString. Читать подробнее
- Дополнительные ошибки значений в PCNTL. Читать подробнее
- Настройки ini для
session.sid_length
иsession.sid_bits_per_character
устарели. Вы можете просто закомментировать их в файле php.ini. Читать подробнее
PHP 8.4 приносит множество инноваций, которые значительно упрощают разработку и повышают производительность. От хуков свойств до улучшений JIT — каждое изменение направлено на то, чтобы сделать код более чистым, безопасным и эффективным. Если вы хотите быть в курсе последних тенденций в мире PHP, обязательно изучите все новые функции PHP 8.4 и внедрите их в свои проекты. Это не только улучшит качество вашего кода, но и позволит вам оставаться конкурентоспособным на рынке разработки.
Не забудьте подписаться на наш блог, чтобы получать уведомления о новых статьях и обновлениях в мире программирования!