Свойства класса теперь поддерживают объявления типов.
<?php
class User
{
public int $id;
public string $name;
}
?>
$user->id
получится
присвоить только значения с типом int, тогда как свойству $user->name
—
только значения с типом string.
Стрелочные функции — сокращённая запись для определения функций с неявной привязкой родительской области видимости по значению.
<?php
$factor = 10;
$nums = array_map(fn ($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
Следующий код теперь будет работать:
<?php
class A {}
class B extends A {}
class Producer
{
public function method(): A {}
}
class ChildProducer extends Producer
{
public function method(): B {}
}
?>
<?php
/**
* Класс удовлетворяет принципу подстановки Б. Ли́сков (англ. Liskov Substitution Principle, LSP),
* поскольку класс C принадлежит подтипу A,
* но при объявлении класса B класс C ещё недоступен
*/
class A
{
public function method(): A {}
}
class B extends A
{
// Fatal error: Could not check compatibility between B::method():C and
// A::method(): A, because class С is not available
public function method(): С {}
}
class C extends B {}
?>
<?php
$array['key'] ??= computeDefault();
// Предыдущая проверка на null с присваиванием — примерно то же, что:
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>
Между знаками числовых литералов теперь допускаются символы подчёркивания.
<?php
6.674_083e-11; // число с плавающей точкой
299_792_458; // десятичное число
0xCAFE_F00D; // шестнадцатеричное число
0b0101_1111; // двоичное число
?>
Слабые ссылки разрешают программисту хранить ссылку на объект, которая не препятствует уничтожению объекта сборщиком мусора, когда ссылок на объект не осталось.
В магическом методе __toString() разрешили выбрасывать исключения. Раньше это вызывало фатальную ошибку. Существующие отлавливаемые фатальные ошибки при преобразовании объекта в строку преобразовали в исключения класса Error.
В дополнение к станадртным названиям файлов класс CURLFile теперь поддерживает потоковые обёртки, если модуль собрали с библиотекой libcurl >= 7.56.0.
Фильтр FILTER_VALIDATE_FLOAT
теперь поддерживает
параметры min_range
и max_range
,
с тем же смыслом, что и фильтр FILTER_VALIDATE_INT
.
FFI — новый модуль, который предлагает простой способ вызова библиотечных функций, доступа к встроенным переменным и способ создавать или обращаться к структурам данных, которые определили в библиотеках на языке Си.
Добавили константу IMG_FILTER_SCATTER
для применения рассеивающегося фильтра к изображениям.
Добавили поддержку алгоритма crc32c
, который вычисляет «хеш» на основе полинома Кастаноли.
С этой реализацией алгоритма CRC32 работают системы хранения наподобие iSCSI, SCTP, Btrfs и ext4.
Добавили функцию mb_str_split(), которая выполняет то же, что и функция str_split(), но работает с кодовыми точками, а не с байтами.
Добавили поддержку предварительной загрузки кода.
Функции preg_replace_callback() и preg_replace_callback_array()
теперь принимают дополнительный аргумент flags
с поддержкой флагов
PREG_OFFSET_CAPTURE
и PREG_UNMATCHED_AS_NULL
.
Он повлияет на формат массива совпавших значений, передаваемого в callback-функцию.
Имя пользователя и пароль как часть DSN-строки разрешили указывать для драйверов mysql, mssql, sybase, dblib, firebird и oci. Раньше это поддерживалось только для драйвера pgsql. Конструктор будет приоритетнее, если имя пользователя с паролем указали и в конструкторе, и в DSN-строке.
В SQL-запросах разрешили экранировать вопросительные знаки, чтобы
они не воспринимались как заполнители параметров.
Запись ??
отправит один знак вопроса в базу данных,
и разрешит, например при работе с СУБД PostgreSQL, указывать оператор ?
,
чтобы проверить, содержит ли столбец JSON конкретный ключ.
Для драйвера теперь доступен метод PDOStatement::getColumnMeta().
Вызов PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)
проверит, доступен ли подготовленный запрос только для чтения,
т. е. не изменяет ли запрос базу данных.
При установке PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true)
методы PDO::errorInfo() и PDOStatement::errorInfo()
возвращают расширенные коды ошибок СУБД SQLite3.
Добавили метод SQLite3::lastExtendedErrorCode(), который получает последний расширенный код ошибки.
Добавили метод SQLite3::enableExtendedResultCodes($enable = true)
,
который заставит метод SQLite3::lastErrorCode()
возвращать расширенные коды ошибок.
Функция strip_tags() теперь также принимает массив разрешённых тегов:
вместо strip_tags($str, '<a><p>')
теперь можно написать strip_tags($str, ['a', 'p'])
.
Добавили новый механизм сериализации пользовательских объектов
через два новых магических метода: __serialize
и __unserialize
.
<?php
// Метод возвращает массив с данными для сохранения целостного состояния объекта
public function __serialize(): array {}
// Восстанавливает состояние объекта из массива данных
public function __unserialize(array $data): void {}
?>
Функции array_merge() и array_merge_recursive()
стали поддерживать вызов без аргументов. При вызове без аргументов функции возвращают пустой массив.
Функции также полезно вызывать с распаковкой аргумента spread-оператором: array_merge(...$arrays)
.
Функция proc_open() теперь принимает массив вместо строки для выполнения команды. При таком вызове процесс открывается напрямую, без командной оболочки, а PHP экранирует аргументы, если потребуется.
<?php
proc_open(['php', '-r', 'echo "Привет, мир\n";'], $descriptors, $pipes);
?>
Функция proc_open() теперь поддерживает
дескрипторы redirect
и null
.
<?php
// То же самое, что и 2>&1 в командной оболочке
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// То же самое, что и 2>/dev/null или 2>nul в командной оболочке
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>
Функция password_hash() теперь поддерживает варианты хеширования argon2i и argon2id из модуля Sodium, если PHP собрали без библиотеки libargon.