Спустя год после старта разработки вышел релиз языка программирования PHP 8.1. В версию добавили ряд улучшений.
Изменения в PHP 8.1 включают:
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);
$valueAfterResuming = Fiber::suspend('after suspending');
// …
});
$valueAfterSuspending = $fiber->start();
$fiber->resume('after resuming');
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 1, "b" => 2]
public function __construct(
private Logger $logger = new NullLogger(),
) {}
}
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
$foo = foo(...);
$foo(a: 1, b: 2);
foreach ($value as $val) {
echo $val;
}
count($value);
}
function dd(mixed $input): never
{
exit;
}
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 public const X = "foo";
}
class Bar extends Foo
{
public const X = "bar";
> Fatal error: Bar::X cannot override final constant Foo::X
}
fwrite($file, "Some content");
if (fsync($file)) {
echo "File has been successfully persisted to disk.";
}
fclose($file);
016 === 0O16; // true
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);
by_ref($GLOBALS);
$a = [];
$a[15.5]; // deprecated, as key value loses the 0.5 component
$a[15.0]; // ok, as 15.0 == 15
Изменения в PHP 8.1 включают:
- поддержку перечислений (enum). Вместо класса с константами теперь можно использовать следующую конструкцию:
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:
$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%, а WordPress — на 3,5%;
- включение оператора распаковки внутри массивов "...$var", что позволит выполнять подстановку существующих массивов при определении нового, расширение поддержки строковых ключей. Теперь можно использовать в коде:
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 1, "b" => 2]
- использование ключевого слова "new" в инициализаторах, чтобы применять объекты в качестве значений параметров по умолчанию, статических переменных, глобальных констант и в аргументах атрибутов, а также при создании вложенных атрибутов:
public function __construct(
private Logger $logger = new NullLogger(),
) {}
}
- возможность пометки свойств класса для доступа только для чтения (информация в подобные свойства может быть записана только один раз):
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')):
$foo = foo(...);
$foo(a: 1, b: 2);
- полноценная поддержка пересечений типов (intersection types), чтобы создавать новые типы, значения которых должны подпадать одновременно под несколько типов. Пересечения требуют наличия в заполняемом множестве не любого из перечисленных типов, а всех указанных типов:
foreach ($value as $val) {
echo $val;
}
count($value);
}
- новый тип "never", который можно использовать для информирования статических анализаторов о том, что функция прекращает выполнение программы, например, вызывая исключение или выполняя функцию exit:
function dd(mixed $input): never
{
exit;
}
- новую функцию array_is_list, которая позволяет определить, что ключи в массиве расположены в порядке увеличения числовых значений, начиная с 0:
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":
{
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 для принудительного сохранения изменений из дискового кэша:
fwrite($file, "Some content");
if (fsync($file)) {
echo "File has been successfully persisted to disk.";
}
fclose($file);
- возможность использования префиксов "0o" и "0O" для восьмеричных чисел, помимо ранее применявшегося префикса "0":
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 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
Спустя год после старта разработки вышел релиз языка программирования PHP 8.1. В версию добавили ряд улучшений. Изменения в PHP 8.1 включают: поддержку перечислений (enum). Вместо класса с...
habr.com