php 7.2里遇到的一些语法不兼容的问题

2.93K 浏览开发笔记

php 7.2里遇到的一些语法不兼容的问题

m2升级到2.3.0,php升级到7.2后,会报一些语法错误。语法有很多改动。不向前兼容。

做一个简单的总结,没有涵盖全部改动,因为不常见。

number_format()不会返回-0

因为-0这种写法很古怪,所以number_format(-0.01),会返回0。

对数组强制转成对象时,会将整形key转成string

直接看代码,

$a = [0 => 1];  $a = (object)$a;  print_r($a->{0});  //或者 print_r($a->{'0'});

现在允许这么写。但是key已经变成string类型,即’0’。

不可以对不能count的对象调用count函数

没有实现Countable接口的对象都不能调用count函数,比如 count(1),count(‘a’) 在之前都会返回1,但是在7.2版本以后,会返回一个E_WARNING级别的错误,并且也不能对字符串进行count,看一个例子:

class _count implements Countable{     public function count() {         return 10;     }}     $count = new _count();     echo count($count);  // 10

可以对__PHP_Incomplete_Class类型的对象调用is_object方法

__PHP_Incomplete_Class,这个东西就是有一个对象,php没有找到定义它的地方,就会把该对象的类型变成这个,举个例子:

$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}'; print_r( unserialize($serialized_object) ); // __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => a [value] => 100 )在解序列化的时候很常见,可以用unserialize_callback_func选项去避免,举个例子: $serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}'; ini_set('unserialize_callback_func', 'mycallback'); // 设置回调print_r( unserialize($serialized_object) ); function mycallback($classname) {     require_once $classname.".php";}

而在7,2版本对__PHP_Incomplete_Class对象调用is_object(),会返回true。

使用一个未定义的常量,会产生一个E_WARNING级别的错误。

echo NAME;// Warning: Use of undefined constant NAME

bcmod函数对于浮点数的操作

在之前,bcmod对于浮点数的运算类似于%操作符,但是在新版类似于fmod。

echo bcmod(4,3.5);  // 之前会返回1,现在会返回1,5

对象返回类型声明

如果参数类型声明指定函数参数的预期类型,则返回类型声明指定返回值的预期类型。

返回类型声明指定了一个函数应该返回的变量的类型。
从PHP 7.2开始,我们被允许为对象数据类型使用返回类型声明。这里是一个例子:

class MyClass {     public $var = 'Hello World'; } $myclass = new MyClass; function test(MyClass $arg) : object {     return $arg; } echo test($myclass)->var;

以前的PHP版本会导致以下致命错误:

Fatal error: Uncaught TypeError: Return value of test() must be an instance of object, instance of MyClass returned in /app/index.php:10

当然,在PHP 7.2中,这个代码回应了“Hello World”。

参数类型加宽

PHP目前不允许子类和它们的父类或接口之间的参数类型有任何差异。这意味着什么?
考虑下面的代码:

<?php class MyClass {     public function myFunction(array $myarray) { /* ... */ } } class MyChildClass extends MyClass {     public function myFunction($myarray) { /* ... */ } }

这里我们省略了子类中的参数类型。在PHP 7.0中,这段代码会产生以下警告:

Warning: Declaration of MyChildClass::myFunction($myarray) should be compatible with MyClass::myFunction(array $myarray) in %s on line 8

自PHP 7.2以来,我们被允许在不破坏任何代码的情况下省略子类中的类型。这个建议将允许我们升级类来在库中使用类型提示,而不需要更新所有的子类。

在列表语法中尾随逗号

数组中最后一项之后的尾随逗号是PHP中的有效语法,有时为了方便追加新项目并避免由于缺少逗号而导致解析错误,鼓励使用该语法。自PHP 7.2以来,我们被允许在分组命名空间中使用尾随逗号。

请参阅列表语法中的尾随逗号以便在此RFC处获得更近的视图以及一些代码示例。

参数类型声明

从PHP 5开始,我们可以在函数的声明中指定期望传递的参数类型。如果给定的值是不正确的类型,那么PHP会抛出一个错误。参数类型声明(也称为类型提示)指定预期要传递给函数或类方法的变量的类型。

例如下面这个例子:

class MyClass {     public $var = &#39;Hello World&#39;; } $myclass = new MyClass; function test(MyClass $myclass){     return $myclass->var; } echo test($myclass);

在这个代码中,测试函数需要MyClass的一个实例。不正确的数据类型将导致以下致命错误:

Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of MyClass, string given, called in /app/index.php on line 12 and defined in /app/index.php:8

由于PHP 7.2 类型提示可以与对象数据类型一起使用,并且这种改进允许声明通用对象作为函数或方法的参数。这里是一个例子:

class MyClass {     public $var = &#39;&#39;; } class FirstChild extends MyClass {     public $var = &#39;My name is Jim&#39;; } class SecondChild extends MyClass {     public $var = &#39;My name is John&#39;; } $firstchild = new FirstChild; $secondchild = new SecondChild; function test(object $arg) {     return $arg->var; } echo test($firstchild); echo test($secondchild);

在这个例子中,我们调用了两次测试函数,每次调用都传递一个不同的对象。在以前的PHP版本中这是不可能的。

参考 https://www.kancloud.cn/php-jdxia/jdxia-phpnote/466633

最后于 5月前 被admin编辑 ,原因:
0