После года разработки представлен релиз языка программирования PHP 8.1. Новая ветка включает серию новых возможностей, а также несколько изменений, нарушающих совместимость.
Ключевые улучшения в PHP 8.1:
Ключевые улучшения в PHP 8.1:
- Добавлена поддержка перечислений (enum), например, вместо класса с константами теперь можно использовать следующую конструкцию:
enum Status {
case Pending;
case Active;
case Archived;
}
class Post
{
public function __construct(
private Status $status = Status:ending;
) {}
public function setStatus(Status $status): void
{
// …
}
}
$post->setStatus(Status::Active);
- Добавлена поддержка легковесных потоков, именуемых файберами (Fiber) и дающими возможность управлять потоками выполнения на низком уровне. Файберы позволяют определять блоки кода, выполнение которых может быть приостановлено и возобновлено по аналогии с генераторами, но из любой позиции стека. Непосредственно файберы не обеспечивают одновременное выполнение потоков и требуют определения цикла обработки событий, но при этом дают возможность использовать один и тот же API в коде, работающем в блокирующем и неблокирующем режимах. Поддержку файберов планируется добавить во фреймворки Amphp и ReactPHP.
$fiber = new Fiber(function (): void {
$valueAfterResuming = Fiber::suspend('after suspending');
// …
});
$valueAfterSuspending = $fiber->start();
$fiber->resume('after resuming');
- Улучшена реализация кэша объектного кода (opcache), в которой появилась возможность кэширования информации о наследовании классов. Оптимизация позволила поднять производительность некоторых приложений на 5-8%. Из других изменений, влияющих на производительность, отмечается оптимизация работы JIT, реализация поддержки JIT для архитектуры ARM64 (AArch64), ускорение разрешения имён классов, оптимизация библиотек timelib и ext/date, повышение производительности сериализации и десериализации, оптимизация функций get_declared_classes(), explode(), strtr(), strnatcmp() и dechex(). В общем виде отмечается повышение производительности Symfony Demo на 23.0%, а WordPress на 3.5%.
- Оператор распаковки внутри массивов "...$var", позволяющий выполнять подстановку существующих массивов при определении нового массива, расширен поддержкой строковых ключей (ранее поддерживались только цифровые идентификаторы). Например, теперь можно использовать в коде:
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 1, "b" => 2]
- Разрешено использовать ключевое слово "new" в инициализаторах, что позволяет использовать объекты в качестве значений параметров по умолчанию, статических переменных, глобальных констант и в аргументах атрибутов. Также возможно создание вложенных атрибутов.
class MyController {
public function __construct(
private Logger $logger = new NullLogger(),
) {}
}
- Предоставлена возможность пометки свойств класса для доступа только для чтения (информация в подобные свойства может быть записана только один раз, после чего не будет доступна для изменения).
class PostData {
public function __construct(
public readonly string $title,
public readonly DateTimeImmutable $date,
) {}
}
$post = new Post('Title', /* … */);
$post->title = 'Other';
> Error: Cannot modify readonly property Post::$title
- Реализован новый синтаксис для вызываемых объектов (callable) - замыкание теперь можно сформировать, вызвав функцию и передав ей в качестве аргумента значение "..." (т.е. для получения ссылки на функцию можно использовать myFunc(...) вместо Closure::fromCallable('myFunc')):
function foo(int $a, int $b) { /* … */ }
$foo = foo(...);
$foo(a: 1, b: 2);
- Добавлена полноценная поддержка пересечений типов (intersection types), позволяющих создавать новые типы, значения которых должны подпадать одновременно под несколько типов. В отличие от union-типов, определяющих коллекции из двух и более типов, пересечения требуют наличия в заполняемом множестве не любого из перечисленных типов, а всех указанных типов.
function count_and_iterate(Iterator&Countable $value) {
foreach ($value as $val) {
echo $val;
}
count($value);
}
- Появился новый тип "never", который можно использовать для информирования статических анализаторов о том, что функция прекращает выполнение программы, например, вызывая исключение или выполняя функцию exit.
function dd(mixed $input): never
{
exit;
}
- Предложена новая функция array_is_list, позволяющая определить, что ключи в массиве расположены в порядке увеличения числовых значений, начиная с 0:
$list = ["a", "b", "c"];
array_is_list($list); // true
$notAList = [1 => "a", 2 => "b", 3 => "c"];
array_is_list($notAList); // false
$alsoNotAList = ["a" => "a", "b" => "b", "c" => "c"];
array_is_list($alsoNotAList); // false
- Для запрета переопределения констант родительского класса теперь можно использовать ключевое слово "final".
class Foo
{
final public const X = "foo";
}
class Bar extends Foo
{
public const X = "bar";
> Fatal error: Bar::X cannot override final constant Foo::X
}
- Предложены функции fsync и fdatasync для принудительного сохранения изменений из дискового кэша.
$file = fopen("sample.txt", "w");
fwrite($file, "Some content");
if (fsync($file)) {
echo "File has been successfully persisted to disk.";
}
fclose($file);
- Добавлена возможность использования префиксов "0o" и "0O" для восьмеричных чисел, помимо ранее применявшегося префикса "0".
016 === 0o16; // true
016 === 0O16; // true
- Выборочно ограничено применение $GLOBALS, что приведёт к нарушению обратной совместимости, но даст возможность значительно ускорить операции с массивами. В том числе запрещена запись в $GLOBALS и передача $GLOBALS по указателю. Анализ 2000 пакетов показал, что только 23 из них затронет данное изменение. Например, прекращена поддержка таких выражений, как:
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);
by_ref($GLOBALS);
- Объявлены устаревшими неявные несовместимые преобразования чисел с плавающей запятой (float) в целочисленное представление (int), приводящие к потере точности. Например, изменение применимо при преобразовании значений ключей массивов, принудительном объявлении целочисленных типов и в операторах, работающих только с целыми числами.
$a = [];
$a[15.5]; // deprecated, as key value loses the 0.5 component
$a[15.0]; // ok, as 15.0 == 15
- Внутренние методы теперь должны возвращать корректный тип. В PHP 8.1 при возвращении типа, не соответствующего объявлению функции, будут выводиться предупреждение, но в PHP 9.0 предупреждение будет заменено на ошибку.
- Продолжена работа по переводу функций c использования ресурсов на манипуляцию объектами. На объекты переведены функции finfo_* и imap_*.
- Объявлена устаревшей передача значений null в качестве аргументов внутренних функций, помеченных как non-nullable. В PHP 8.1 использование конструкций вида str_contains("string", null) будет приводить к предупреждению, а в PHP 9 к ошибке.
- Объявлен устаревшим программный интерфейс Serializable.
- Во многих модулях ресурсы преобразованы в объекты (file_info -> finfo в FileInfo, FTP\Connection, IMAP\Connection, LDAP\Connection|Result, PgSql\Connection|Result, PSpell\Dictionary, GdFont в GD и т.п.).
- Добавлена поддержка алгоритмов хэширования MurmurHash3 и xxHash.
Релиз языка программирования PHP 8.1
www.opennet.ru