探索 PHP 8.3 中的新功能和增强功能

2023-10-22 18:57:28 浏览数 (1)

简介

PHP 8.3 引入了许多新特性,同时也弃用了不少功能,以及其他变更。在本文中,我将尝试解释最新版本PHP(8.3)的新功能。8.3 中有许多新功能,这使我的默认编码语言更加优雅和开发人员友好。

PHP可以轻松地使用本机PHP在桌面编程中使用。当然,还有许多其他工具可以在桌面编程中使用php,但我觉得原生PHP比它们更酷。无论如何,让我们开始深入了解我们的新功能。

主要新特性

  • 类型化的类常量 (Typed Class Constants)
  • 支持获取动态的类常量 (dynamic class constant) 和枚举成员 (Enum member)
  • 新增json_validate()函数,用于验证 JSON
  • 添加 Random 扩展
  • 添加mb_str_pad()
  • 添加#[Override]属性
  • 新增更多 PHP Sockets 选项
  • 增加对 cURL 7.87 及以下版本的新 cURL 选项和常量的支持
  • 支持匿名只读类 (anonymous read-only classes)
  • 支持在数组中使用负数索引 (negative indices)

1. Json Validation

我敢打赌,在开发新项目时,我们所有人都会尝试验证字符串是否是 json。此功能将本机方法添加到 php 中,用于验证字符串是否为 json。我知道这是非常酷的补充。

代码语言:javascript复制
$json = '{ "example": "title" }';
$is_json = false;
if (json_validate($json)) {
    // Valid JSON.
    $is_json = true;
} 

// Or better way
$is_json = json_validate($json);

目前,大多数PHP程序员使用该 json_decode() 函数来完成此任务,但这使用内存和处理能力,而这些内存和处理能力并不是仅仅检查有效性所必需的。无需用于 json_decode 验证 json 字符串。

2. Improved unserialize() error handling

改进了反序列化()错误处理。

unserialize() 中的错误处理目前缺乏一致性,因为它有可能根据格式不正确的输入字符串的性质生成E_NOTICE、E_WARNING甚至抛出不可预测的异常或错误。使用新的php功能将涵盖此问题。

在建议的修改之前,在 PHP 中管理反序列化错误的过程可能类似于以下内容:

代码语言:javascript复制
try {
    set_error_handler(static function ($severity, $message, $file, $line) {
        throw new ErrorException($message, 0, $severity, $file, $line);
    });

    $result = unserialize($serialized);
} catch (Throwable $e) {
    // Optional catch block if you wish to handle the unserialization error.
} finally {
    restore_error_handler();
}

var_dump($result);

在此功能之后,我们可以通过以下方式使用:

代码语言:javascript复制
function unserialize(string $data, array $options = []): mixed
{
    try {
        // The existing unserialization logic happens here.
    } catch (Throwable $e) {
        throw new UnserializationFailedException(previous: $e);
    }
}

而反序列化失败异常的实现是

代码语言:javascript复制
class UnserializationFailedException extends Exception
{
}

3. Fetching Class Constants Dynamically

在 8.3 之前,我们不能通过变量获取基于类的常量。当我们调用它们时,我们应该直接添加常量名称。让我们看看如何使用当前版本的 php 获取常量:

代码语言:javascript复制
class StatusCodes {
    const OK = 200;
    const NOT_FOUND = 404;
    const INTERNAL_ERROR = 500;
    const UNAUTHORIZED = 401;
    const FORBIDDEN = 403;
}

// Accessing the constants
echo StatusCodes::OK; // Output: 200
echo StatusCodes::NOT_FOUND; // Output: 404
echo StatusCodes::INTERNAL_ERROR; // Output: 500
echo StatusCodes::UNAUTHORIZED; // Output: 401
echo StatusCodes::FORBIDDEN; // Output: 403

在 8.3 中,我们可以使用变量来获取常量

代码语言:javascript复制
class StatusCodes {
    const OK = 200;
    const NOT_FOUND = 404;
    const INTERNAL_ERROR = 500;
    const UNAUTHORIZED = 401;
    const FORBIDDEN = 403;
}
$variable = "OK";
// Accessing the constants
echo StatusCodes::{$variable} // Output: 200
$variable = "NOT_FOUND";
echo StatusCodes::{$variable} // Output: 404

有了这个,我们可以从类中动态调用常量,我喜欢这个功能。

4. Introducing Read-Only Modifications

引入只读修改

“本提案的目标:克服对深度克隆只读属性的限制”

此建议有助于在 the__clone()magic 方法调用范围内重新初始化只读属性。下面是此增强功能的说明性示例.

8.3 之前

代码语言:javascript复制
class Example {
    public readonly $readOnlyProp = 'Initial Value';
}

$instance = new Example();
$instance->readOnlyProp = 'New Value'; // this will not work

class Example {
    public function __construct(
        public readonly string $readOnlyProp,
    ) {}
  public function __clone()
    {
        $this->readOnlyProp = clone $this->readOnlyProp; // Doesn't work, an error is thrown.
    }
}

8.3 之后

代码语言:javascript复制
class Foo {
    public function __construct(
        public readonly string $example,
        public readonly string $foo
    ) {}

    public function __clone()
    {
        $this->example = clone $this->example; // Works.
        $this->cloneFoo();
    }

    private function cloneFoo()
    {
        unset($this->foo); // Also works.
    }
}

$foo = new Foo('Test', 'Example');

$foo2 = clone $foo;
// No error, Foo2::example is cloned deeply, while Foo2::$foo becomes uninitialized.

5. Typed Constants

众所周知,在 8.3 之前,我们定义了常量,但没有指定类型。就像下面一样

代码语言:javascript复制
class Example
{
    const HTTP_STATUS_OK = 200;
}

您现在可以键入提示类常量

代码语言:javascript复制
class Example
{
   const int HTTP_STATUS_OK = 200;
}

0 人点赞