PHP 的新增功能 8.3

目录

要点

相关赞助内容

评估流处理技术:企业架构师综合指南 

通过低代码 API 策略快速实现现代化

流处理简介

咨询专家:在 Microsoft Azure 上构建智能应用程序

GraphQL 和数据产品:强大的组合,可简化您的数据网格之旅

相关赞助商

设置环境

新的递增/递减运算符

新的 #[\Override] 属性用于标记重写方法  

任意静态变量初始值设定项  

动态类常量查找

新的只读功能

只读属性可以在克隆期间重新初始化

非只读类可以扩展只读类

类型化类常量

随机化器类添加

新的 Randomizer::getBytesFromString() 方法

新的 Randomizer::getFloat() 和 Randomizer::nextFloat() 方法

使 unserialize() 对尾随数据发出警告

新的 json_validate() 函数

小幅弃用

概括


要点

  • PHP 8.3 扩展了 只读 早期 8.x 版本中引入的功能.
  • 新的 #[\Override] 属性显式标记一个方法,该方法是重写方法.
  • 现在可以显式输入类常量.
  • 已添加新功能 Random/Randomizer 班级.
  • 一个新功能 json_validate() 帮助验证 JSON 字符串.

本文是该文章的一部分 文章系列“PHP 8.x". 您可以订阅以接收有关本系列新文章的通知 通过RSS.

PHP 仍然是网络上使用最广泛的脚本语言之一,根据调查,已知服务器端编程语言的所有网站中有 77.3% 使用 PHP 威三科技. PHP 8 带来了许多新功能和其他改进,我们将在本系列文章中对其进行探讨.

相关赞助内容
相关赞助商

​编辑

Hazelcast 通过统一的实时数据平台实现应用程序现代化,以便对数据立即采取行动. 了解更多.

PHP 8.3 是 PHP 8.x 系列的最新重大更新.

除了性能改进之外,它还带来了丰富的新功能,包括对 只读 PHP 8.1 中引入的功能; 显式类型化的类常量; 一个新的 #[\Override] 打算从超类重写的方法的属性; 和更多.

设置环境

下载并安装 PHP 8.3 二进制文件。 在本系列的前几部分中,我们使用 Windows 操作系统。 为了与此保持一致,请下载并安装 PHP 8.3 Windows 二进制文件. 按照详细信息设置环境 PHP 7 - 入门和 OOP 改进. 最后,通过运行验证 PHP 版本是否为 8.3 php --version 在命令行上.

新的递增/递减运算符

PHP 8.3 引入了新的递增和递减函数 str_increment(string $string)str_decrement(string $string) 通过加/减 1 来增加/减少他们的参数。换句话说 $v++ 是相同的 $v += 1$v-- 是相同的 $v -= 1.

这些函数抛出一个 ValueError 如果以下任何一项为真:

  • $string 是空字符串
  • $string 不由字母数字 ASCII 字符组成

此外, str_decrement 函数抛出一个 ValueError 如果字符串不能递减。 例如,“A”或“0”不能递减.
不推荐使用非字母数字字符串的递增/递减。 对于可以解释为科学记数法数字的字符串,不进行类型转换.

在以下示例脚本中, str_increment(string $string) 函数调用会递增一个字母数字字符串。 这  str_decrement(string $string) 函数递减字母数字字符串的值。 该脚本还演示了函数的参数必须是字母数字字符串,或者 ValueError 被抛出:

<?php
 
$str = "1";
$str = str_increment($str);
echo var_dump($str);  

$str = "1";
$str = str_decrement($str);
echo var_dump($str);  

$str = "-1";
$str = str_decrement($str);
echo var_dump($str);  
?>

运行脚本,输出如下:

 string(1) "2"
 string(1) "0"
Uncaught ValueError: str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters ...

类型递增/递减 bool 没有任何作用并且会产生警告。 同样,不推荐对空字符串进行递减或递增,因为它是非数字的。 此外,应该注意的是,对非数字字符串进行递减和递增都没有效果,因此已被弃用。 为了进行演示,请运行以下脚本:

<?php 
// decrementing empty string
$str = "";
--$str;  
echo var_dump($str);
// decrementing non-numeric string
$str = "input";
--$str;  
echo var_dump($str);
// incrementing empty string
$str = "";
++$str;  
echo var_dump
($str);  
// incrementing non-numeric string string
$str = "input";
++$str;  
echo var_dump($str);  

输出包括弃用消息.

Deprecated: Decrement on empty string is deprecated as non-numeric in …
int(-1)
Deprecated: Decrement on non-numeric string has no effect and is deprecated in …
string(5) "input"
Deprecated: Increment on non-alphanumeric string is deprecated in …
string(1) "1"
string(5) "input"

然而,字母数字字符串会递增/递减,尽管输出可能并不总是可预测的。 运行以下脚本:

<?php
$str = "start9";
$str = str_increment($str);
echo var_dump($str);
$str = "end0";
$str = str_decrement($str);
echo var_dump($str);   
$str = "AA";
$str = str_decrement($str);
echo var_dump($str); 

输出如下:

string(5) "input"
string(6) "staru0"
string(4) "enc9"
string(1) "Z"

字符串参数必须在范围内,以免导致下溢。 为了进行演示,请运行以下脚本:

<?php
$str = "00";
$str = str_decrement($str);
echo var_dump($str);  

A ValueError 是输出:

Uncaught ValueError: str_decrement(): Argument #1 ($string) "00" is out of decrement range

新的 #[\Override] 属性用于标记重写方法  

PHP 8.3 引入了  #[\Override] 属性来显式声明重写方法的意图。 这 #[\Override] 引入属性是为了消除方法重写中的任何歧义。 重写方法声明怎么可能不明确呢? PHP 已经验证重写方法的签名是否与父类中相应的重写方法兼容。 PHP 已经验证从接口继承的实现方法是否与给定接口兼容。 PHP 不验证方法是否打算重写父类中的现有方法.

PHP 不验证方法是否打算从接口实现方法。 如果用新的意图声明 #[\Override] 属性使得调试任何由于方法签名相似或由于拼写错误或错误而看似重写方法但并不打算成为重写方法的代码的代码变得更加容易。 标记重写的方法,无论是来自超类还是来自接口,显式地服务于许多目的,包括:

  • 让调试更容易.
  • 重构和清理现有代码.
  • 检测库提供的超类中可能发生的重大更改.

PHP引擎如何解释新的 #[\Override] 属性? 如果将此属性添加到方法中,引擎将在编译时验证父类或任何已实现的接口中是否存在同名的方法。 如果不存在这样的方法,则会发出编译时错误。 这 #[\Override] 属性不会更改重写方法的规则和语法。 它仅向编译器提供提示。 这  #[\Override] 属性满足或可用:

  • 超类或实现的接口的公共和受保护方法,包括抽象方法和静态方法.
  • 使用特征中的抽象方法(a 使用的特质 是在类中使用的一个 use 关键字)如随后的示例所示.

在下面的示例脚本中,类 B 扩展了类 A 并重写了它的三个方法 fn1, fn2fn3.

<?php
class A {
    protected function fn1(): void {}
    public function fn2(): void {}
    private function fn3(): void {}
}
class B extends A {
    #[\Override]
    public function fn1(): void {}
   #[\Override]
    public function fn2(): void {}
    #[\Override]
    public function fn3(): void {}  
}

脚本运行并且 #[\Override] 属性满足前两种方法,但不满足 fn3 因为 fn3 是一个私有方法.

B::fn3() has #[\Override] attribute, but no //matching parent method exists ...

在下一个示例中,一个类扩展另一个类并实现一个接口,重写其唯一的方法。 这 #[\Override] 属性被放置在重写方法上.

<?php
interface B {
    public function fn(): void;
}
class A {
    public function fn(): void {}  
}
class C extends A implements B {
#[\Override]
public function fn(): void {}
}
?>

超类中必须存在匹配的方法。 为了演示这一点,请运行以下脚本,其中包含 #[\Override] 超类中没有匹配方法的方法上的属性.

<?php
class Hello
{
    #[\Override]
    public function hello(): void {}  
}
?>

生成错误消息:

Hello::hello() has #[\Override] attribute, but no matching parent method exists ...

#[\Override] 属性不能应用于 __construct() 方法,如以下脚本所示:

<?php
class Obj  
{
    private $data;
    #[\Override]
    public function __construct() {
        $this->data = "some data";
    }
}

生成错误消息:

Obj::__construct() has #[\Override] attribute, but no matching parent method exists ...

#[\Override] 如果特征未在类中使用,则特征方法上的属性将被忽略。 这 #[\Override] 可以在特征的方法上声明属性,如下所示:

<?php
trait Hello {
    #[\Override]
    public function hello(): void {}
}
?>

但是,如果在类中使用该特征,则 #[\Override] 如果特征的方法不在超类中,则无法在该方法上声明属性。 一个例子:

<?php
trait Hello {
    #[\Override]
    public function hello(): void {}
}
class C {
    use Hello;  
}
?>

生成错误消息:

C::hello() has #[\Override] attribute, but no matching parent method exists ...

不言而喻,并非父类、实现的接口或使用的特征中的所有或任何方法都必须被重写。 否则,从父类、接口或特征继承抽象方法的类如果不提供实现,则可以声明为抽象。 但是,当一个类确实重写了所使用的特征、接口或超类中的方法时,最好(尽管不是必需的)用 #[\Override] 属性.

来自已使用特征的抽象方法在类中被重写满足 #[\Override] 属性。 这意味着从类中使用的特征继承的抽象方法可以在前面/标记 #[\Override] 类中的属性表明这是一个重写方法。 在下面的脚本中, #[\Override] 方法上的属性 hello 表明意图覆盖 hello() 从使用的特征中抽象方法.

<?php
trait Hello {
    abstract public function hello();
    public function hello2() {}
}
class HelloClass {
    use Hello;
    #[\Override]
    public function hello() {
        return "hello";
    }
}
?>

但是,从使用的特征继承的常规方法不能在前面或使用 #[\Override] 属性进行标记,因为它不会真正覆盖任何方法。 它只会“隐藏”某个特征中的方法。 为了进行演示,请考虑以下脚本:

<?php
trait Hello {
    public function hello(){}
    public function hello2() {}
}
class HelloClass {
    use Hello;
    #[\Override]
    public function hello() {
        return "hello";
    }
}
?>

#[\Override] 属性指示重写某些方法的意图,但该类只是“隐藏”属于特征的同名方法。 该脚本生成一条错误消息:

HelloClass::hello() has #[\Override] attribute, but no matching parent method exists  

#[\Override] 属性可以与枚举一起使用。 例如,声明一个接口并在枚举中实现该接口。 覆盖枚举中接口的方法.

<?php
interface Rectangle {
    public function rect(): string;
}
enum Geometry implements Rectangle {
    case Square;
    case Line;
    case Point;
    case Polygon;

    #[\Override]
    public function rect(): string{
        return "Rectangle";
    }
}

#[\Override] 属性可以与匿名类一起使用。 一个例子:

<?php
class Hello {public function hello() {}}
interface HelloI {public function hello2();}
var_dump(new class() extends Hello implements HelloI {
   #[\Override]
  public function hello() {}
   #[\Override]
  public function hello2() {}
});
?>

脚本的输出如下:

object(Hello@anonymous)#1 (0) { }

任意静态变量初始值设定项  

PHP 8.3 添加了对静态变量初始值设定项中的非常量表达式的支持。 在下面的示例中,静态变量初始值设定项 fn2() 是一个函数调用而不是一个常量.

<?php
function fn1() {
    return 5;
}
 
function fn2() {
    static $i = fn1();
    echo $i++, "\n";
}
fn2();
?>

调用函数时脚本返回值 5.

重新声明静态变量在早期版本中是支持的,但在 PHP 8.3 中不再支持。 以下脚本重新声明静态变量初始值设定项.

<?php
function fn1() {
    return 5;
}
function fn2() {
    static $i = 1;
    static $i = fn1();
}
fn2();
?>

脚本运行时生成错误消息:

Duplicate declaration of static variable $i ... 

支持非常量表达式的一个副作用是 ReflectionFunction::getStaticVariables() 方法可能无法在编译时确定静态变量的值,因为静态变量初始值设定项使用的表达式只有在调用函数后才知道其值。 如果静态变量的值无法在编译时确定,则值为 NULL 返回如下例所示:

<?php
function getInitValue($initValue) {
    static $i = $initValue;
}
var_dump((new ReflectionFunction('getInitValue'))->getStaticVariables()['i']);

接下来,修改脚本以调用 getInitValue 函数,该函数初始化静态变量:

<?php
function getInitValue($initValue) {
    static $i = $initValue;
}
getInitValue(1);
var_dump((new ReflectionFunction('getInitValue'))->getStaticVariables()['i']);
?>

这次,同样 ReflectionFunction 调用返回初始化值 int(1).

但是,一旦将值添加到静态变量表中,就无法使用另一个函数调用重新初始化,例如:

getInitValue(2);

静态变量的值仍然是 int(1) 如以下脚本的输出所示,其内容为: int(1) int(1).

<?php
function getInitValue($initValue) {
    static $i = $initValue;
}
getInitValue(1);
var_dump((new ReflectionFunction('getInitValue'))->getStaticVariables()['i']);
getInitValue(2); 
var_dump((new ReflectionFunction('getInitValue'))->getStaticVariables()['i']);
?>

在静态变量初始值设定项中允许非常量表达式的另一个副作用是,如果在初始化期间引发异常,则静态变量不会显式初始化并获得初始值 NULL, 但后续调用可能能够初始化静态变量.

另一个副作用是依赖于另一个静态变量的静态变量的初始值在编译时是未知的。 在以下脚本中,静态变量 $b’s 值只有在之后才知道 setInitValue() 叫做.

<?php
function setInitValue() {
   static $a = 0;
   static $b = $a + 1;
   var_dump($b);
}
setInitValue();
?>

输出是:

int(1)

动态类常量查找

PHP 8.3 引入了新的语法来查找类常量。 PHP 8.3 之前 constant() 必须使用函数来查找类常量,如下所示:

<?php
class C {
    const  string SOME_CONSTANT = 'SCRIPT_LANG';
}

$some_constant = 'SOME_CONSTANT';

var_dump(constant(C::class . "::{$some_constant}"));

输出是 :

string(11) "SCRIPT_LANG"

在 PHP 8.3 中,查找类常量的语法简化如下:

<?php
class C {
    const  string SOME_CONSTANT = 'SCRIPT_LANG';
}

$some_constant = 'SOME_CONSTANT';

var_dump(C::{$some_constant});

输出是:

string(11) "SCRIPT_LANG"

新的只读功能

正如我们在一篇文章中所描述的 较早的文章 这个系列的, readonly 属性是在 PHP 8.1 中引入的,而 readonly PHP 8.2 中添加了类。 PHP 8.3 采用 readonly 通过添加两个新功能进一步增强功能:

  • 只读属性可以在克隆期间重新初始化.
  • 非只读类可以扩展只读类.

只读属性可以在克隆期间重新初始化

用于深度克隆 readonly 属性,即 readonly 属性可以在克隆期间重新初始化。 首先,我们从一个深度克隆的示例开始,当脚本使用 PHP 8.2 运行时,深度克隆会失败。 这 readonly 以下脚本中的属性是 RO::$c.  

<?php
class C {
    public string $msg = 'Hello';
}

readonly class RO {
    public function __construct(
        public C $c
    ) {}

    public function __clone(): void {
        $this->c = clone $this->c;
    }
}

$instance = new RO(new C());
$cloned = clone $instance;

当脚本运行时,会产生错误:

Uncaught Error: Cannot modify readonly property RO::$c ...

以下脚本演示了修改 PHP 中的只读属性 8.3.

<?php
class C {
    public string $msg = 'Hello';
}

readonly class RO {
    public function __construct(
        public C $c
    ) {}

    public function __clone(): void {
        $this->c = clone $this->c;
    }
}

$instance = new RO(new C());
$cloned = clone $instance;
$cloned->c->msg = 'hello';
echo $cloned->c->msg;

输出如下:

hello

重新初始化只能在执行期间执行 __clone() 魔术方法 称呼。 被克隆的原始对象没有被修改; 只能修改新实例。 因此,从技术上讲,对象仍然是不变的。 重新初始化只能执行一次。 也可以执行取消设置只读属性的值,并被视为重新初始化.  

在下一个示例中,类 A 声明两个只读属性 $a 和 $b, 这是由初始化的 __construct() 功能。 这 __clone() 方法重新初始化只读属性 $a,而只读属性 $b 通过调用来取消设置 cloneB() 功能.

<?php
class A {
   public readonly int $a;
   public readonly int $b;
   public function __construct(int $a,int $b) {     
       $this->a = $a;
       $this->b = $b;
   }
 public function __clone()
    {
        $this->a = clone $this->a;  
        $this->cloneB();
    }
    private function cloneB()
    {
        unset($this->b);  
    }
}

克隆对象并修改其只读属性不会更改原始对象的只读属性值.

$A = new A(1,2);
echo $A->a;
echo $A->b;
$A2 = clone $A;
echo $A->a;
echo $A->b;

readonly 属性分别保持相同的值 1 和 2.

重新初始化相同 readonly 属性两次会产生错误。 例如,如果将以下行添加到 __clone() 方法:

$this->a = clone $this->a;

生成以下错误消息:

Uncaught Error: __clone method called on non-object ...

非只读类可以扩展只读类

对于 PHP 8.3,非-readonly 课程可以延长 readonly 类。 作为示例,以下脚本声明了一个 readonly 班级 A 具有三个属性,它们是隐式的 readonly. 这 readonly 属性在类构造函数中初始化.

<?php
readonly class A
{
    public int $a;
    public string $b;
    public array $c;
    
    public function __construct() {
        $this->a = 1;
        $this->b = "hello";
        $this->c = ["1" => "one",
                    "2" => "two"];
    }
}

然后,上课 B, 这是非只读的,扩展了类 A.   

class B extends A {}

该类会在 PHP 中生成错误 8.2:

Non-readonly class B cannot extend readonly class A ...

但属性在 readonly 班级 A 无法在扩展类中重新定义,因为属性是隐式只读的.

class B extends A {public int $a;}

A readonly 类仍然无法扩展非-readonly 班级.

一个非-readonly 类扩展a readonly 类不会隐式创建扩展类 readonly.

虽然一个 readonly 类不能声明非类型化属性或静态属性、非类型属性-readonly 类扩展a readonly 类可以声明非类型化属性或静态属性。 以下脚本演示了这一点:

<?php
trait T {
    public $a1;        // Untyped property
}
class B extends A {
    use T;
    public static $a2; // Static property
}

类型化类常量

PHP 8.3 添加了对类型化类常量的支持。 类型化类常量可以添加到类、接口、枚举和特征中。 类型化类常量意味着类常量可以与显式类型关联.

在 PHP 8.3 之前,类常量没有显式类型,因此子类可以分配与定义类中使用的类型不同类型的值。 在 PHP 8.3 中,可以输入常量,例如使用类型 string. 类型常量 string 只能分配一个 string 值,但不是其他类型的值,即使在派生类中也是如此.

在下面的示例中,类型常量 int 被分配了一个 string 价值.

<?php
interface I {
    const  string SOME_CONSTANT = 'SCRIPT_LANG';
}

class C implements I {
    const int  ANOTHER_CONSTANT = I::SOME_CONSTANT;
}

生成错误消息:

Cannot use int as value for class constant C::ANOTHER_CONSTANT of type string

mixed 类型可以分配给常量,如示例所示:

<?php
interface I {
    const  string SOME_CONSTANT = 'SCRIPT_LANG';
}

class C implements I {
    const mixed  ANOTHER_CONSTANT = 1;
}

任何 PHP 类型都可以分配给类常量,除了 void, never, 和 callable.

随机化器类添加

PHP 8.3 添加了三个新方法 \Random\Randomizer 班级。 新方法提供了通常需要的功能。 一个函数从给定字符串中生成随机选择的字节,另外两个函数生成随机浮点值.

新的 Randomizer::getBytesFromString() 方法

该方法返回给定长度的字符串,该字符串由给定字符串中随机选择的字节组成.

方法定义如下:

public function getBytesFromString(string $string, int $length): string {}  

该方法的示例脚本如下:

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

$bytes = $randomizer->getBytesFromString(
        'some string input',
        10);

echo bin2hex($bytes);

输出是:

7467736f7473676e6573

新的 Randomizer::getFloat() 和 Randomizer::nextFloat() 方法

getFloat() 方法返回作为方法参数提供的最小值和最大值之间的随机浮点值.

$boundary 参数值决定是否 $min$max 价值观是包容性的。 换句话说, $boundary 参数确定返回值是否可以是其中之一 $min$max 价值观.

枚举值确定间隔,如表中所述:

价值    间隔    描述
关闭打开(默认)[$最小,最大$)包括下限
排除上限
已关闭已关闭[$最小,最大$]包括下限
包括上限
打开关闭($最小,最大$]排除下限
包括上限
打开打开($最小,最大$)排除下限
排除上限

举个例子, getFloat() 在脚本中返回 1 到 2 之间的随机浮点值:

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

$f = $randomizer->getFloat(1,2); 

echo var_dump($f);

输出如下:

float(1.3471317682766972)

这 $最大限度 arg 必须大于 $min arg 但必须是有限的.

下一个示例演示了不同边界的使用.

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

$f = $randomizer->getFloat(1,3,\Random\IntervalBoundary::OpenOpen); 

echo var_dump($f);
$f = $randomizer->getFloat(1,3,\Random\IntervalBoundary::ClosedOpen); 

echo var_dump($f);
$f = $randomizer->getFloat(1,3,\Random\IntervalBoundary::OpenClosed); 

echo var_dump($f);
$f = $randomizer->getFloat(1,3,\Random\IntervalBoundary::ClosedClosed); 

echo var_dump($f);

多次调用脚本生成的输出是:

float(2.121058113021827) float(1.4655805702205025) float(1.8986188544040883) float(1.2991440175378313)

float(2.604249570497203) float(1.8832264253121545) float(2.127150199054182) float(2.5601957175378405)

float(2.0536414161355174) float(2.5310859684773384) float(1.5561747808441186) float(2.4747482582046323)

float(2.8801657134532497) float(1.9661050785744774) float(1.0275149347491048) float(2.6876762894295947)

float(2.0566100272261596) float(1.2481323630515981) float(2.378377362548793) float(2.365791373823495)

nextFloat() 方法返回区间 [0, 1) 内的随机浮点数。 该方法相当于 getFloat(0, 1, \Random\IntervalBoundary::ClosedOpen).

使 unserialize() 对尾随数据发出警告

unserialize() 函数之前只考虑主数据,忽略序列化值尾部分隔符之后的额外数据,即 ‘;’ 对于标量和 ‘}’ 对于数组和对象。 在 PHP 8.3 中,尾随字节不会被忽略,并且会输出警告消息。 示例脚本:

<?php
var_dump(unserialize('i:1;'));
var_dump(unserialize('b:1;i:2;'));

生成警告消息:

unserialize(): Extra data starting at offset 4 of 8 byte ...

新的 json_validate() 函数

PHP 8.3 添加了一个急需的新函数来验证字符串参数是否是有效的 JSON。 字符串参数必须是 UTF-8 编码的字符串。 该函数返回一个布尔值(true 或 false)来指示字符串是否是有效的 JSON。 PHP 8.3 之前的版本,可以按如下方式创建验证 JSON 的自定义函数:

<?php
function json_validate(string $string): bool {
    json_decode($string);

    return json_last_error() === JSON_ERROR_NONE;
}

但是 json_validate() 函数不是内置函数。 以下不包含自定义函数定义的脚本在使用 PHP 之前版本运行时会生成错误 8.3:

<?php 
 
var_dump(json_validate('{ "obj": { "k": "v" } }'));

错误信息是:

Uncaught Error: Call to undefined function json_validate()

随着 PHP 8.3 中新的 json_validate() 函数的支持,以下脚本运行正常:

<?php
 
var_dump(json_validate('{ "obj": { "k": "v" } }'));

输出是:

bool(true)

小幅弃用

PHP 8.3 弃用了某些未使用的小功能.

传递阴性 $widthsmb_strimwidth() 已被弃用。 必须在以下位置启用多字节扩展 php.ini 使用该功能的配置文件:

extension=mbstring

以下脚本传递负宽度 -2 到函数.

<?php
echo mb_strimwidth("Hello", 0, -2, "...");
?>

运行脚本时,会输出以下弃用消息:

Deprecated: mb_strimwidth(): passing a negative integer to argument #3 ($width) is deprecate...

其次, NumberFormatter::TYPE_CURRENCY 常量已被弃用。 启用国际化扩展以使用常量.

extension=intl

运行以下脚本:

<?php
$fmt = numfmt_create( 'de_DE', NumberFormatter::TYPE_CURRENCY);
$data = numfmt_format($fmt, 1234567.891234567890000);
?>

输出弃用消息:

Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in C:\PHP\scripts\sample.php on line 2

MT_RAND_PHP 为特殊情况实现而引入的常量没有任何重要用途,因此已被弃用。 运行以下使用常量的脚本.

<?php
echo mt_rand(1,  MT_RAND_PHP), "\n";

输出弃用消息:

Deprecated: Constant MT_RAND_PHP is deprecated ...

ldap_connect 函数用于检查给定的连接参数是否可以连接到 LDAP 服务器,已弃用使用两个参数分别指定主机和端口的函数签名:

ldap_connect(?string $host = null, int $port = 389): LDAP\Connection|false

在php.ini中启用ldap扩展来使用该功能.

extension=ldap

运行以下脚本:

<?php
$host ='example.com';
$port =389;
ldap_connect($host,$port;
?>

输出弃用消息:

Deprecated: Usage of ldap_connect with two arguments is deprecated ...

概括

作为回顾,本文讨论了 PHP 8.3 中的显着新功能,包括对早期 8.x 版本中引入的只读功能的一些修改, #[\Override] 属性来显式装饰一个方法,该方法是一个重写方法、显式类型化的类常量和新的方法 json_validate() 验证 JSON 字符串的函数.

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值