
PHP 8.3 于 11 月 23 日如期发布,它包含了自 发布以来的许多新功能和改进。尽管官方认为这只是一个次要版本,但 8.3 中的一些变化可能会直接影响到你的 PHP 工作-也许能帮助你更快地编写代码,减少 bug。
让我们深入了解一下这个最新版本所带来的重大变化(有时并不那么重大)。
让我们先来看看 PHP 8.3 中最引人注目的功能。
从 PHP 7.4 开始,我们就可以为类属性声明类型了。然而,尽管多年来对 PHP 类型进行了多次调整,但直到现在才扩展到常量。
在 PHP 8.3 中,类常量(也包括接口、特质和枚举常量)可以进行类型化,这样开发人员就不太可能偏离常量最初声明的意图了。
下面是一个使用接口的基本示例:
// Legal: interface ConstTest { // Declared type and value are both strings const string VERSION = "PHP 8.3"; } // Illegal: interface ConstTest { // Type and value mi *** atch in this initial declaration const float VERSION = "PHP 8.3"; }
这些的真正价值是在处理从基本声明派生出来的类时显现出来的。虽然子类可以经常为常量赋新值,但 PHP 8.3 可以帮助防止意外改变常量的类型,使其与初始声明不兼容:
class ConstTest {
const string VERSION = "PHP 8.2";
}
class MyConstTest extends ConstTest {
// Legal:
// It's OK to change the value of VERSION here
const string VERSION = "PHP 8.3";
// Illegal:
// Type must be declared if it was specified in the base class
const VERSION = "PHP 8.3";
// Illegal:
// In this case, we can't change the type declared in the
// base class, even if the new type and its value are compatible.
const float VERSION = 8.3;
}
请记住,在 “narrowing” 多个类型或使用其他兼容类型时,分配给类常量的类型可能会不同:
class ConstTest {
const string|float VERSION = "PHP 8.2";
}
class MyConstTest extends ConstTest {
// Legal:
// Here, it's OK to narrow the type declaration to string or float
const string VERSION = "PHP 8.3";
const float VERSION = 8.3;
// Legal:
// Value could be an int, but it's compatible with float
const float VERSION = 8;
// Illegal:
// We can't widen the type options here to include int
const string|float|int VERSION = 8;
}
在验证返回值时,其他属性支持的两种类型 – void 和 never – 不支持作为类常量类型。
json_validate() 函数在处理 *** ON 编码数据时,很高兴能在尝试对其进行处理之前知道有效载荷在语法上是否有效。
在以前的 PHP 版本中,开发人员使用 json_decode() 函数,并在该函数尝试将 *** ON 数据转换为关联数组或对象时检查错误。PHP 8.3 的新 函数可以在不使用构建数组或对象结构所需的全部内存的情况下进行错误检查。
因此,在过去,您可能会像这样验证 *** ON 有效负载:
$obj = json_decode($maybe *** ON);
if (json_last_error() === *** ON_ERROR_NONE) {
// Probably do something with $obj
}
如果您不打算立即对上例中的 $obj 执行操作,那么仅仅确认原始 *** ON 有效负载的有效性就会占用大量资源。在 PHP 8.3 中,您可以这样做来节省一些内存:
if (json_validate($maybe *** ON) {
// Do something with $maybe *** ON
}
注:使用 json_validate() ,然后立即通过 json_decode() 运行数据,无论如何都会占用 decode 的内存资源,这样做意义不大。您更有可能使用新函数来验证 *** ON,然后再将其存储到某个地方或作为请求响应交付。
readonly 属性将单个类属性声明为 readonly 的功能出现在 中。PHP 8.2 引入了将该属性分配给的功能。然而,许多开发人员认为,在使用包含此类属性的类时受到的限制妨碍了有用的编程。
This code example from the RFC shows how it works:
一份关于修改 行为的 RFC 提出了两项建议:
readonly 类readonly 属性第二项建议已被引入 PHP 8.3。新 *** 允许在 __clone 魔术 *** 中(包括通过在 __clone 中调用的函数)重新初始化具有 readonly 属性的类实例。
RFC 中的代码示例展示了它是如何工作的:
class Foo {
public function __construct(
public readonly DateTime $bar,
public readonly DateTime $baz
) {}
public function __clone() {
// $bar will get a new DateTime when clone is invoked
$this->bar = clone $this->bar;
// And this function will be called
$this->cloneBaz();
}
private function cloneBaz() {
// This is legal when called from within __clone
unset($this->baz);
}
}
$foo = new Foo(new DateTime(), new DateTime());
$foo2 = clone $foo;
#[\Override] 属性在 PHP 中实现接口时,程序员会为这些接口中命名的 *** 提供详细的功能。在创建类的实例时,程序员可以通过在子类中创建具有相同名称和兼容签名的替代版本来覆盖父类 *** 。
一个问题是,程序员可能会认为他们是在实现接口 *** 或覆盖父 *** ,其实不然。由于子类 *** 的名称有错别字,或者由于父类代码中的 *** 被删除或重命名,他们可能会创建一个完全独立的怪兽。
PHP 8.3 引入了 #[\Override] 属性,以帮助程序员明确 *** 必须在代码中具有一定的沿袭关系。
下面是一个基本例子:
class A {
protected function ovrTest(): void {}
}
// This will work because ovrTest()
// can be found in the parent class
class B extends A {
#[\Override]
public function ovrTest(): void {}
}
// This will fail because ovrBest()
// (probably a typo) is not in the parent
class C extends A {
#[\Override]
public function ovrBest(): void {}
}
与 PHP 代码中的其他属性不同,使用变量名获取类常量和枚举成员有点复杂。在 PHP 8.3 之前,您可能会使用 constant() 函数来获取常量,如下所示:
class MyClass {
public const THE_CONST = 9;
}
enum MyEnum int {
case FirstMember = 9;
case SecondMember = 9;
}
$constantName = 'THE_CONST';
$memberName = 'FirstMember';
echo constant('MyClass::' . $constantName);
echo constant('MyEnum::' . $memberName)->value;
现在,使用上面相同的类和枚举定义,就可以通过 PHP 8.3 的获取功能实现相同的结果:
$constantName = 'THE_CONST';
$memberName = 'FirstMember';
echo MyClass::{$constantName};
echo MyEnum::{$memberName}->value;
getBytesFromString() *** 您是否曾想过使用预先批准的字符集生成随机字符串?现在有了 *** ,您就可以轻松实现这个愿望了,该 *** 已添加到 PHP 8.3 的随机扩展中。
这个新 *** 很简单:将字符串作为源材料传给它,并指定要使用的字符个数。然后,该 *** 将从字符串中随机选择字节,直到达到指定长度为止。
下面是一个简单的示例:
$rando = new Random\Randomizer(); $alpha = 'ABCDEFGHJKMNPQRSTVWXYZ'; $rando->getBytesFromString($alpha, 6); // "MBXGWL" $rando->getBytesFromString($alpha, 6); // "LESPMG" $rando->getBytesFromString($alpha, 6); // "NVHWXC"
随机输出所要求的长度有可能比输入字符串的字节数还多:
$rando = new Random\Randomizer(); $nums = '123456'; $rando->getBytesFromString($nums, 10); // "2526341615"
输入字符串中的每个字符都是独一无二的,每个字符被随机结果选中的几率相等。不过,可以通过让输入字符比其他字符出现得更频繁来对它们进行加权。例如
$rando = new Random\Randomizer(); $weighted = 'AAAAA12345'; $rando->getBytesFromString($weighted, 5); // "1AA53" $rando->getBytesFromString($weighted, 10); // "42A5A1AA3A"
getFloat() 和 nextFloat() *** 在扩展随机扩展的同时,PHP 8.3 引入了两个生成随机浮点数值的新 *** : getFloat() 和 nextFloat() 。
下面是一个例子:
$rando = new Random\Randomizer(); // Generate a float value between a minimum // value of 0 and a maximum value of 5 $rando->getFloat(0,5); // 2.3937446906217
getFloat() *** 在最小值和更大值之后还接受第三个参数。使用 Random\IntervalBoundary 枚举可以确定函数是否可以返回最小值和更大值。
以下是规则:
使用 getFloat() 而不指定 Enum 作为第三个参数时,默认值是 IntervalBoundary::ClosedOpen。
中提供了一个有用的示例,可以随机生成经纬度坐标,其中纬度可以包括 -90 和 90,但经度不能包括 -180 和 180(因为它们是相同的):
$rando = new Random\Randomizer(); printf( "Lat: %+.6f Long: %+.6f", $rando->getFloat(-90, 90, \Random\IntervalBoundary::ClosedClosed), // -180 will not be used $rando->getFloat(-180, 180, \Random\IntervalBoundary::OpenClosed), );
新的 nextFloat() *** 与使用 getFloat() *** 请求范围从 0 到小于 1 的随机值基本相同:
$rando = new Random\Randomizer(); $rando->nextFloat(); // 0.3767414902847
PHP 8.3 还包括许多其他新功能和小改动。我们将在下文中提及它们,并提供其他资源的链接(如有):
ldap_connect_wallet() 和 ldap_exop_sync() .mb_str_pad() 多字节字符串函数。ReflectionMethod::createFromMethodName() *** 。在 PHP 的每个新版本中,都会有一些函数和设置被标记为最终将被删除。这些功能一旦被弃用,就不建议继续使用,当它们出现在执行代码中时,会在许多日志中生成通知。
下面是 PHP 8.3 中的弃用功能列表,并附有其他信息的链接:
3MT_RAND_PHP Mt19937 变体已被弃用。ReflectionClass::getStaticProperties() 不再为空。get_class() 和 get_parent_class() 已被弃用。我们查看了 PHP 8.3 中的重大变化。要查看该版本中每项更新的详细列表,请查阅该版本的。如果您计划将代码转移到运行最新 PHP 的平台上,《》可能会帮您避免麻烦。
如果你负责在开发或生产服务器上安装 PHP,8.3 现在就了。
宝塔面板中的网站管理是非常重要的一部分,也是站长经常需要使用到的功能模块。网站管理,主要用于管理和创建WEB站点。如果您是宝塔面板的使用用户,应该对此模块有充分的了解,以便于您更高效地管理网站。 宝塔面板网站管理模块包括:添加新网站、修改默认页、设置默认站点、站点列表、站点的运行与停止、备份站点、...
每台连接到Internet的计算机都有一个Internet协议 (IP) 地址。但是,并非所有IP地址的外观或行为都相同。 如果您使用计算机网络或服务器,了解动态IP和静态IP之间的区别至关重要。通过详细了解每个协议,您可以选择最适合您需求的解决方案。 在本文中,我们将讨论静态和动态IP之间...
Node.js和PHP是Web开发工作中常用的两种基本Web技术。两者都为服务器端开发做出了贡献,Node.js甚至同时服务于客户端和服务器端开发。 PHP已经为开发人员服务了近3年,现在它为78%的网络提供支持。相比之下,Node.js相对较新,但扩展速度非常快,由于其全栈开发能力而成为流行...
当您开始使用网页设计时,让一切正常工作并查看您希望它看起来如何的关键元素落在 CSS 手中。这是层叠样式表的缩写,它们允许您以任何您想要的方式设置HTML元素的样式。 虽然您可以通过多种方式尝试CSS(通常是内联方式),但还有更好的方式来实现它。这符合您应该遵循的一系列最佳实践,以确保您的代码...
当前是固态驱动器 (SSD)的时代,因为消费类机械硬盘驱动器 (HDD)已经过时。SSD的显着优势之一是即使在没有电源运行的情况下,它也可以将数据存储在闪存芯片中。SSD在启动设备、启动应用程序和传输数据方面提供快速性能。 自2000年代初以来,串行高级技术附件 (SATA)驱动程序已通过高级...
是用于移动和Web应用程序开发的最流行的库之一。React由Facebook创建,包含一组可重用的JavaScript代码片段,用于构建称为组件的用户界面 (UI)。 重要的是要注意ReactJS不是JavaScript框架。那是因为它只负责渲染应用程序视图层的组件。React是和等框架的替代...