简介
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
代码语言:javascript复制在 8.3 中,我们可以使用变量来获取常量
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;
}