PHP 8.4.1 Released!
выпущен!
PHP 8.4 — большое обновление языка PHP.
Оно содержит множество новых возможностей, таких как хуки свойств, асимметричная область видимости свойств, обновление DOM API, улучшена производительность, исправлены ошибки и многое другое.

Хуки свойств RFC Документация

PHP < 8.4
class Locale
{
private
string $languageCode;
private
string $countryCode;

public function
__construct(string $languageCode, string $countryCode)
{
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getLanguageCode(): string
{
return
$this->languageCode;
}

public function
setLanguageCode(string $languageCode): void
{
$this->languageCode = $languageCode;
}

public function
getCountryCode(): string
{
return
$this->countryCode;
}

public function
setCountryCode(string $countryCode): void
{
$this->countryCode = strtoupper($countryCode);
}

public function
setCombinedCode(string $combinedCode): void
{
[
$languageCode, $countryCode] = explode('_', $combinedCode, 2);

$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getCombinedCode(): string
{
return
\sprintf("%s_%s", $this->languageCode, $this->countryCode);
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->getCountryCode()); // BR
var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR
PHP 8.4
class Locale
{
public
string $languageCode;

public
string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}

public
string $combinedCode
{
get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[
$this->countryCode, $this->languageCode] = explode('_', $value, 2);
}
}

public function
__construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR
Хуки свойств обеспечивают поддержку вычисляемых свойств, которые могут быть понятны IDE и инструментам статического анализа, без необходимости писать DocBlock-комментарии, которые могут не совпадать. Кроме того, они позволяют выполнять надёжную предварительную или последующую обработку значений, без необходимости проверять, существует ли в классе соответствующий геттер или сеттер.

Асимметричная область видимости свойств RFC Документация

PHP < 8.4
class PhpVersion
{
private
string $version = '8.3';

public function
getVersion(): string
{
return
$this->version;
}

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
PHP 8.4
class PhpVersion
{
public private(
set) string $version = '8.4';

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
Область видимости записи свойства теперь может контролироваться независимо от области видимости чтения свойства, что уменьшает необходимость использования шаблонных методов-геттеров для раскрытия значения свойства без возможности его изменения извне класса.

Атрибут #[\Deprecated] RFC Документация

PHP < 8.4
class PhpVersion
{
/**
* @deprecated 8.3 use PhpVersion::getVersion() instead
*/
public function getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.3';
}
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();
PHP 8.4
class PhpVersion
{
#[
\Deprecated(
message: "use PhpVersion::getVersion() instead",
since: "8.4",
)]
public function
getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.4';
}
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();
Новый атрибут #[\Deprecated] расширяет существующий механизм объявления сущности устаревшей для пользовательских функций, методов и констант классов.

Новые возможности ext-dom и поддержка HTML5 RFC RFC Документация

PHP < 8.4
$dom = new DOMDocument();
$dom->loadHTML(
<<<'HTML'
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)
PHP 8.4
$dom = Dom\HTMLDocument::createFromString(
<<<HTML
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)

Новый DOM API, который поддерживает разбор HTML5-документов в соответствии со стандартами, исправляет несколько давних ошибок в поведении DOM и добавляет несколько функций, делающих работу с документами более удобной.

Новый DOM API доступен в пространстве имён Dom. Документы, использующие новый DOM API, могут быть созданы с помощью классов Dom\HTMLDocument и Dom\XMLDocument.

Объектно-ориентированный API для BCMath RFC

PHP < 8.4
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo
$result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
PHP 8.4
use BcMath\Number;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo
$result; // '2.12345'
var_dump($num1 > $num2); // false

Новый объект BcMath\Number позволяет использовать объектно-ориентированный стиль и стандартные математические операторы при работе с числами произвольной точности.

Эти объекты неизменяемы и реализуют интерфейс Stringable, поэтому их можно использовать в строковых контекстах, например, echo $num.

Новые функции array_*() RFC

PHP < 8.4
$animal = null;
foreach ([
'dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
if (
str_starts_with($value, 'c')) {
$animal = $value;
break;
}
}

var_dump($animal); // string(3) "cat"
PHP 8.4
$animal = array_find(
[
'dog', 'cat', 'cow', 'duck', 'goose'],
static fn (
string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"
Добавлены функции array_find(), array_find_key(), array_any() и array_all().

SQL-парсеры, специфичные для драйверов PDO RFC

PHP < 8.4
$connection = new PDO(
'sqlite:foo.db',
$username,
$password,
);
// object(PDO)

$connection->sqliteCreateFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);

$connection->query('SELECT prepend_php(version) FROM php');
PHP 8.4
$connection = PDO::connect(
'sqlite:foo.db',
$username,
$password,
);
// object(Pdo\Sqlite)

$connection->createFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);
// Does not exist on a mismatching driver.

$connection->query('SELECT prepend_php(version) FROM php');
Добавлены дочерние классы Pdo\Dblib, Pdo\Firebird, Pdo\MySql, Pdo\Odbc, Pdo\Pgsql, Pdo\Sqlite драйверов, наследующие PDO.

new MyClass()->method() без скобок RFC Документация

PHP < 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.3';
}
}

var_dump((new PhpVersion())->getVersion());
PHP 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.4';
}
}

var_dump(new PhpVersion()->getVersion());
К свойствам и методам только что инициализированного объекта теперь можно обращаться, не оборачивая выражение new в круглые скобки.

Новые классы, интерфейсы и функции

  • Добавлены ленивые объекты.
  • Новая реализация JIT на основе IR Framework.
  • Добавлена функция request_parse_body().
  • Добавлены функции bcceil(), bcdivmod(), bcfloor() и bcround().
  • Добавлено перечисление RoundingMode для функции round() с 4 режимами: TowardsZero, AwayFromZero, NegativeInfinity и PositiveInfinity.
  • Добавлены методы DateTime::createFromTimestamp(), DateTime::getMicrosecond(), DateTime::setMicrosecond(), DateTimeImmutable::createFromTimestamp(), DateTimeImmutable::getMicrosecond() и DateTimeImmutable::setMicrosecond().
  • Добавлены функции mb_trim(), mb_ltrim(), mb_rtrim(), mb_ucfirst() и mb_lcfirst().
  • Добавлены функции pcntl_getcpu(), pcntl_getcpuaffinity(), pcntl_getqos_class(), pcntl_setns() и pcntl_waitid().
  • Добавлены методы ReflectionClassConstant::isDeprecated(), ReflectionGenerator::isClosed() и ReflectionProperty::isDynamic().
  • Добавлены функции http_get_last_response_headers(), http_clear_last_response_headers(), fpow().
  • Добавлены методы XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(), XMLWriter::toStream(), XMLWriter::toUri() и XMLWriter::toMemory().
  • Добавлена функция grapheme_str_split().

Устаревшая функциональность и изменения в обратной совместимости

  • Модули IMAP, OCI8, PDO_OCI и pspell перенесены из ядра в PECL.
  • Типы параметров, неявно допускающие значение null объявлены устаревшими.
  • Использование _ в качестве имени класса объявлено устаревшим.
  • Возведение нуля в степень отрицательного числа объявлено устаревшим.
  • Передача некорректного режима в функцию round() выбрасывает ошибку ValueError.
  • Константы классов модулей date, intl, pdo, reflection, spl, sqlite и xmlreader типизированы.
  • Класс GMP теперь является окончательным.
  • Удалены константы MYSQLI_SET_CHARSET_DIR, MYSQLI_STMT_ATTR_PREFETCH_ROWS, MYSQLI_CURSOR_TYPE_FOR_UPDATE, MYSQLI_CURSOR_TYPE_SCROLLABLE и MYSQLI_TYPE_INTERVAL.
  • Функции mysqli_ping(), mysqli_kill(), mysqli_refresh(), методы mysqli::ping(), mysqli::kill(), mysqli::refresh() и константы MYSQLI_REFRESH_* объявлены устаревшими.
  • Функции stream_bucket_make_writeable() и stream_bucket_new() теперь возвращают экземпляр класса StreamBucket вместо stdClass.
  • Изменение поведения языковой конструкции exit().
  • Константа E_STRICT объявлена устаревшей.
To Top