PHP8.2新特性

只读类

可以使用readonly属性修饰类,它会将只读属性添加到每一个属性里,且不允许创建动态属性,而且也不支持使用#[\AllowDynamicProperties]来创建动态属性。

readonly class BlogData
{
    public string $title;

    public Status $status;

    public function __construct(string $title, Status $status)
    {
        $this->title = $title;
        $this->status = $status;
    }
}

使用#[\AllowDynamicProperties]声明动态属性将会报错

<?php
#[\AllowDynamicProperties]
readonly class Foo {
}

// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
?>

只读类中的属性需要指定类型

<?php
readonly class Foo
{
    public $bar;
}

// Fatal error: Readonly property Foo::$bar must have type
?>

只读类中的属性不能设为静态类型

<?php
readonly class Foo
{
    public static int $bar;
}

// Fatal error: Readonly class Foo cannot declare static properties
?>

只读子类只能继承只读类!言外之意就是只读类的子类必须是只读类型。

析取范式 (DNF) 类型

现在null和false可以用作独立类型了。

class Foo {
    public function bar((A&B)|null $entity) {
        return $entity;
    }
}

类型添加null、false、true

可以单独使用它们。

class Falsy
{
    public function alwaysFalse(): false { /* ... */ *}

    public function alwaysTrue(): true { /* ... */ *}

    public function alwaysNull(): null { /* ... */ *}
}

新的随机数扩展类

类名为:Random\Randomizer,可以使用对象的方式生成随机数。

简单演示:

<?php
$r = new \Random\Randomizer();

// Random integer in range:
echo $r->getInt(1, 100), "\n";
?>

复杂演示:

use Random\Engine\Xoshiro256StarStar;
use Random\Randomizer;

$blueprintRng = new Xoshiro256StarStar(
    hash('sha256', "Example seed that is converted to a 256 Bit string via SHA-256", true)
);

$fibers = [];
for ($i = 0; $i < 8; $i++) {
    $fiberRng = clone $blueprintRng;
    // Xoshiro256**'s 'jump()' method moves the blueprint ahead 2**128 steps, as if calling
    // 'generate()' 2**128 times, giving the Fiber 2**128 unique values without needing to reseed.
    $blueprintRng->jump();

    $fibers[] = new Fiber(function () use ($fiberRng, $i): void {
        $randomizer = new Randomizer($fiberRng);

        echo "{$i}: " . $randomizer->getInt(0, 100), PHP_EOL;
    });
}

// The randomizer will use a CSPRNG by default.
$randomizer = new Randomizer();

// Even though the fibers execute in a random order, they will print the same value
// each time, because each has its own unique instance of the RNG.
$fibers = $randomizer->shuffleArray($fibers);
foreach ($fibers as $fiber) {
    $fiber->start();
}

traits中定义常量

可以通过类来访问traits中的常量。

trait Foo
{
    public const CONSTANT = 1;
}

class Bar
{
    use Foo;
}

var_dump(Bar::CONSTANT); // 1
var_dump(Foo::CONSTANT); // Error

移除动态属性

允许stdClass类使用动态属性,其它类使用将会报Deprecated notice错误,除非在类上声明#[\AllowDynamicProperties]属性。

class User
{
    public $name;
}

$user = new User();
$user->last_name = 'Doe'; // Deprecated notice

$user = new stdClass();
$user->last_name = 'Doe'; // Still allowed

__get/__set 2个魔术方法不受此影响。

新增类、接口和方法

New mysqli_execute_query function and mysqli::execute_query method.
New #[\AllowDynamicProperties] and #[\SensitiveParameter] attributes.
New ZipArchive::getStreamIndex, ZipArchive::getStreamName, and ZipArchive::clearError methods.
New ReflectionFunction::isAnonymous and ReflectionMethod::hasPrototype methods.
New curl_upkeep, memory_reset_peak_usage, ini_parse_quantity, libxml_get_external_entity_loader, sodium_crypto_stream_xchacha20_xor_ic, openssl_cipher_key_length functions.

移除的特性

Deprecated ${} string interpolation.
Deprecated utf8_encode and utf8_decode functions.
Methods DateTime::createFromImmutable and DateTimeImmutable::createFromMutable has a tentative return type of static.
Extensions ODBC and PDO_ODBC escapes the username and password.
Functions strtolower and strtoupper are no longer locale-sensitive.
Methods SplFileObject::getCsvControl, SplFileObject::fflush, SplFileObject::ftell, SplFileObject::fgetc, and SplFileObject::fpassthru enforces their signature.
Method SplFileObject::hasChildren has a tentative return type of false.
Method SplFileObject::getChildren has a tentative return type of null.
The internal method SplFileInfo::_bad_state_ex has been deprecated.