PHP 8.3的新特性
PHP 8.3 will be released on November 23, 2023; it has improvements to readonly classes, the new json_validate()
function, additions to the recently added Randomizer
class, stack overflow detection, and more.
PHP 8.3将于2023年11月23日发布; 它改进了只读类、新的 json_validate()函数、添加了最近添加的随机化类、堆栈溢出检测等等。
In this post, we'll go through all features, performance improvements, changes and deprecations one by one.
在这篇文章中,我们将逐一介绍所有的特性、性能改进、更改和废弃。
Readonly amendments 只读方案 rfc
This RFC proposed two changes, only one was accepted: being able to reinitialize readonly properties while cloning. That might sound like a very big deal, but this RFC only addresses a very specific (but important) edge case: overwriting property values within __clone()
, in order to allow deep cloning readonly properties.
这个 RFC 提出了两个更改,只有一个被接受: 能够在克隆时重新初始化只读属性。这听起来似乎是一件大事,但是这个 RFC 只处理一个非常特殊(但是重要)的边缘情况: 在 __clone ()中覆盖属性值,以便允许深度克隆只读属性。
readonly class Post
{
public function __construct(
public DateTime $createdAt,
) {}
public function __clone()
{
$this->createdAt = new DateTime();
// This is allowed,
// even though `createdAt` is a readonly property.
}
}
You can read an in-depth post about this RFC and some sidenotes here.
你可以在这里阅读一篇关于这个 RFC 的深度文章和一些旁注。
Anonymous readonly classes 匿名只读类 upgrading升级中
Previously, you weren't able to mark anonymous classes as readonly. That's fixed in PHP 8.3:
在此之前,您无法将匿名类标记为 readonly,这在 PHP 8.3中得到了修复:
$class = new readonly class {
public function __construct(
public string $foo = 'bar',
) {}
};
The newjson_validate()
function全新的方法
Previously, the only way to validate whether a string was valid JSON, was to decode it and detect whether any errors were thrown. This new json_validate()
function is beneficial if you only need to know whether the input is valid JSON, since it uses less memory compared to decoding the string.
以前,验证字符串是否为有效 JSON 的唯一方法是对其进行解码并检测是否抛出了任何错误。如果您只需要知道输入是否是有效的 JSON,那么这个新的 JSON _ valid()函数是有益的,因为与解码字符串相比,它使用的内存更少。
json_validate(string $json, int $depth = 512, int $flags = 0): bool
Randomizer
additions 附加条件 rfc
PHP 8.2 added the new Randomizer class. This update brings some small additions:
PHP 8.2添加了新的随机数发生器类,这个更新带来了一些小的补充:
Randomizer::getBytesFromString(string $string, int $length): string
This method allows you to generate a string with a given length that consists of randomly selected bytes from a given string.
此方法允许您生成具有给定长度的字符串,该字符串由从给定字符串中随机选择的字节组成。
Randomizer::getFloat(
float $min,
float $max,
IntervalBoundary $boundary = IntervalBoundary::ClosedOpen
): float
getFloat()
returns a float between $min
and $max
. You can define whether $min
and $max
should be included thanks to the IntervalBoundary
enum. Closed
means the value is included, while Open
means excluded.
GetFloat ()返回 $min 和 $max 之间的浮点数。您可以定义是否应该包含 $min 和 $max,这要感谢 IntervalEdge 枚举。“封闭”表示包含值,而“开放”表示排除值。
Randomizer::nextFloat(): float {}
Finally, nextFloat()
is a shorthand for getFloat(0, 1, IntervalBoundary::ClosedOpen)
, in other words: it'll give you a random float between 0 and 1, where 1 is excluded.
最后,nextFloat ()是 getFloat (0,1,IntervalBorder: : Closed Open)的简写,换句话说: 它会给你一个介于0和1之间的随机浮点数,其中1被排除在外。
Dynamic class constant fetch 动态类常量提取 rfc
PHP 8.3 allows you to fetch constants with a more dynamic syntax:
PHP 8.3允许使用更动态的语法获取常量:
class Foo
{
const BAR = 'bar';
}
$name = 'BAR';
// Instead of this:
constant(Foo::class . '::' . $name);
// You can now do this:
Foo::{$name};
More Appropriate Date/Time Exceptions 更适当的日期/时间异常 rfc breaking崩溃了
In many cases, PHP would simply throw an Exception
or Error
object; or emit a warning or error when something went wrong in dealing with dates and times. This RFC goes through all those edge cases and adds proper, dedicated exceptions for them.
在许多情况下,PHP 只是抛出一个 Exception 或 Error 对象; 或者在处理日期和时间出错时发出一个警告或错误。这个 RFC 遍历了所有这些边缘情况,并为它们添加了适当的、专用的异常。
We now have exceptions like DateMalformedIntervalStringException
, DateInvalidOperationException
, and DateRangeError
.
现在我们有了诸如 DateMalformedIntervalStringException、 DateInvalidOperationException 和 DateRangeError 等异常。
In general, these additions won't break any code, since these newly added exceptions and errors subclass the generic Exception
and Error
classes. However, there are three small breaking changes that come with this RFC:
通常,这些新增的异常和错误不会破坏任何代码,因为这些新增的异常和错误是一般的 Exception 和 Error 类的子类。然而,这种 RFC 带来了三个小的突破性变化:
-
The
Epoch doesn't fit in a PHP integer
now returns a newDateRangeError
instead of a genericValueError
, which it does not subclass. This is only an issue for 32-bit platforms. -
Epoch 不适合 PHP 整数,现在返回一个新的 DateRangeError,而不是一般的 ValueError,它没有子类化。这只是32位平台的一个问题。
-
The
Only non-special relative time specifications are supported for subtraction
warning withDateTime::sub()
anddate_sub()
becomes a newDateInvalidOperationException
. -
使用 DateTime: : sub ()和 date _ sub ()成为一个新的 DateInvalidOperationException 时,只支持非特殊的相对时间规范用于减法警告。
-
The
Unknown or bad format (%s) at position %d (%c): %s
andString '%s' contains non-relative elements
warnings that are created while parsing wrong/brokenDateInterval
strings will now throw a newDateMalformedIntervalStringException
when used with the OO interface, instead of showing a warning and returning false. -
位置% d (% c)处的未知或错误格式(% s) :% s 和 String’% s’包含在解析错误/中断的 DateInterval 字符串时创建的非相对元素警告,当与 OO 接口一起使用时,现在将抛出一个新的 DateMalformedIntervalStringException,而不是显示警告并返回 false。
Improved 进步了 unserialize()
error handling 错误处理 rfc
unserialize()
will now always emit a E_WARNING
when running into problems instead of sometimes an E_NOTICE
.
Unseralize ()现在在遇到问题时总是发出 E _ WARWN,而不是有时发出 E _ NOTICE。
This RFC also proposed adding more exceptions when running unserialize()
, but that part didn't get accepted.
此 RFC 还建议在运行 unSeries ()时添加更多异常,但该部分没有被接受。
Stack overflow detection 堆栈溢出检测 pr公关
PHP 8.3 adds two new ini directives called zend.max_allowed_stack_size
and zend.reserved_stack_size
. Programs that are close to overflowing the call stack may now throw an Error when using more than the difference between zend.max_allowed_stack_size
and zend.reserved_stack_size
.
PHP 8.3添加了两个新的 ini 指令 zend.max _ allow _ stack _ size 和 zend.reserve _ stack _ size。接近溢出调用堆栈的程序现在可能会在使用超过 zend.max _ allow _ stack _ size 和 zend.reserve _ stack _ size 之间的差值时抛出错误。
The benefit of this feature is that stack-overflow-induced segmentation faults won't result in segfaults anymore, making debugging a lot easier.
这个特性的好处是,由堆栈溢出引起的分段错误不会再导致 Segfault 错误,从而使调试变得更加容易。
The default for zend.max_allowed_stack_size
is 0
, meaning PHP will automatically determine a value. You can also provide -1
to indicate there isn't a limit, or a specific number of bytes. The zend.reserved_stack_size
directive is used to determine the "buffer zone", so that PHP is able to still throw an error instead of actually running out of memory. The value here should be a number of bytes, but PHP will determine a reasonable default for you, so you don't necessarily need to set it, unless you're running into edge cases for specific programs.
Zend.max _ allow _ stack _ size 的默认值为0,这意味着 PHP 将自动确定一个值。您还可以提供 -1来表示没有限制,或者没有特定的字节数。使用 zend.reserve _ stack _ size 指令确定“缓冲区”,这样 PHP 仍然能够抛出错误,而不是实际上耗尽内存。这里的值应该是一定数量的字节,但 PHP 会为您确定一个合理的默认值,所以您不一定需要设置它,除非您遇到特定程序的边缘情况。
On a final note, for fibers, the existing fiber.stack_size
directive is used as the max allowed stack size.
最后,对于光纤,使用现有的 fiber.stack _ size 指令作为允许的最大堆栈大小。
zend.max_allowed_stack_size=128K
Small, but notable changes 虽然变化不大,但很明显
Not every change in PHP passes the RFC process. In fact, the majority of changes include maintenance and bugfixing, and don't require an RFC. All of these changes are listed in the UPGRADING document. I'll list some of the most prominent ones, but you should definitely read throughout the whole list if you want to know about the tiniest details.
并非 PHP 中的每个更改都通过 RFC 进程。实际上,大多数更改包括维护和错误修复,并且不需要 RFC。所有这些更改都在升级文档中列出。我会列出一些最突出的,但是如果你想知道最微小的细节,你绝对应该阅读整个列表。
-
When using FFI, C functions that have a return type of
void
now returnnull
instead of returningFFI\CData:void
-
在使用 FFI 时,返回 void 类型的 C 函数现在返回 null 而不是返回 FFI CData: void
-
posix_getrlimit()
now takes an optional$res
parameter to allow fetching a single resource limit. -
Posx _ getrlimit ()现在接受一个可选的 $res 参数,以允许获取单个资源限制。
-
gc_status()
has four new fields:running
,protected
,full
, andbuffer_size
. -
Gc _ status ()有四个新字段: running、 protected、 full 和 buffer _ size。
-
class_alias()
now supports creating an alias of an internal class. -
Class _ alias ()现在支持创建内部类的别名。
-
mysqli_poll()
now raises aValueError
when the read nor error arguments are passed. -
Mysqli _ poll ()现在在传递 read 和 error 参数时引发 ValueError。
-
array_pad()
is now only limited by the maximum number of elements an array can have. Before, it was only possible to add at most 1048576 elements at a time. -
Array _ pad ()现在只受到数组可以拥有的最大元素数的限制。在此之前,一次最多只能添加1048576个元素。
-
New posix functions:
posix_sysconf()
,posix_pathconf()
,posix_fpathconf()
, andposix_eaccess()
-
新的 posx 函数: posx _ sysconf ()、 posx _ pathconf ()、 posx _ fpathconf ()和 posx _ eaccess ()
-
Executing
proc_get_status()
multiple times will now always return the right value on posix systems. -
多次执行 proc _ get _ status ()现在总是返回 posx 系统上的正确值。