PHP Migrating to 7.2 7.3

2023-08-23 18:51:21 浏览数 (1)

  • 实验环境:https://onlinephp.io/

  • Polyfill https://github.com/symfony/polyfill/tree/main/src

PHP7.1 to PHP7.2

https://www.php.net/manual/en/migration72.php Argon2 password hashing support, class constant visibility, object type, and many more.

New Features 7.2

代码语言:javascript复制
// 新的 object 类型
// 可用于逆变(contravariant)参数输入和协变(covariant)返回任何对象类型
// https://www.php.net/manual/zh/language.oop5.variance.php
// 协变使子类比父类方法能返回更具体的类型;逆变使子类比父类方法参数类型能接受更模糊的类型
function test(object $obj) : object
{
    return new SplQueue();
}
test(new StdClass());
代码语言:javascript复制
// 抽象类可以重写被继承的抽象类的抽象方法
abstract class A
{
    abstract function test(string $s);
}
abstract class B extends A
{
    // overridden - 仍然保持参数的逆变和返回的逆变
    abstract function test($s): int;
}
代码语言:javascript复制
// 重写方法和接口实现的参数类型可以省略
// 仍然是符合LSP,这种参数类型是逆变
interface A
{
    public function test(array $input);
}
class B implements A
{
    // type omitted for $input
    public function test($input){
        return $input;
    }
}
var_dump((new B())->test(1));
// PHP72
// int(1)
//
// PHP71
// Fatal error: Declaration of B::test($input) must be compatible with A::test(array $input)

Backward incompatible changes 7.2

代码语言:javascript复制
// 防止 number_format() 返回负零
var_dump(number_format(-0.01));
// PHP72
// string(1) "0"
//
// PHP71
// string(2) "-0"
代码语言:javascript复制
// 转换对象和数组中的数字键
$arr = [0 => 1];
$obj = (object) $arr;
var_dump($obj);
var_dump($obj->{'0'}, // 新写法
    $obj->{0} // 新写法
);
// PHP72
// object(stdClass)#1 (1) {
//   ["0"]=>
//   int(1)
// }
// int(1)
// int(1)
//
// PHP71
// object(stdClass)#1 (1) {
//   [0]=>
//   int(1)
// }
// Notice: Undefined property: stdClass::$0


$obj = new class {
    public function __construct()
    {
        $this->{1} = "value";
    }
};
$arr = (array) $obj;
var_dump($arr);
var_dump($arr["1"]); // 整数 或者 字符串整数 含义相同
var_dump($arr[1]); // PHP71
var_dump($arr[0]);
// PHP72
// array(1) {
//   [1]=>
//   string(2) "my"
// }
//
// PHP71 无法取整型字符串 key
// array(1) {
//   ["1"]=>
//   string(2) "my"
// }
// Notice: Undefined offset: 1
// Notice: Undefined offset: 1
// Notice: Undefined offset: 0

$a = [1.3 => "v1", 1.4 => "v2"];
var_dump($a);
// ALL array key float 会被转换为 int
// array(1) {
//   [1]=>
//   string(2) "v2"
// }
代码语言:javascript复制
// get_class() 函数不再接受 null
var_dump(get_class(null));
// PHP72
// Warning: get_class() expects parameter 1 to be object
// bool(false)
//
// PHP71
// Warning: get_class() called without object from outside a class
// bool(false)
//
// PHP80
// Fatal error: Uncaught TypeError: get_class(): Argument #1 ($object) must be of type object, null given
代码语言:javascript复制
// 计算非可数类型(non-countable)时发出警告
var_dump(
    count(null), // NULL is not countable
    count(1), // integers are not countable
    count('abc'), // strings are not countable
    count(new stdclass) // objects not implementing the Countable interface are not countable
);
// PHP72
// Warning: count(): Parameter must be an array or an object that implements Countable
//
// PHP71
// 无 Warning
//
// PHP80
// Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array
代码语言:javascript复制
// 调用未定义的常量,现在会抛出一个 E_WARNING 错误(之前版本中为 E_NOTICE))
// PHP8 将不会转化成他们自身的字符串,同时抛出 Error 异常
var_dump(MY_CONST);
// PHP72
// Warning: Use of undefined constant MY_CONST - assumed 'MY_CONST'
// string(8) "MY_CONST"
//
// PHP71
// Notice: Use of undefined constant MY_CONST
// string(8) "MY_CONST"
//
// PHP80
// Fatal error: Uncaught Error: Undefined constant "MY_CONST"
代码语言:javascript复制
// bcmod 任意精度数字取模,添加新增参数 scale
var_dump(bcmod("4", "3.5"));
// PHP72
// string(1) "0"
//
// PHP71
// string(1) "1"
var_dump(bcmod("4", "3.5", 1));
// PHP72
// string(3) "0.5"
//
// PHP71
// Warning: bcmod() expects exactly 2 parameters, 3 given
代码语言:javascript复制
// json_decode associative 允许为 null
// 当为 true 时,JSON 对象将返回关联 array;当为 false 时,JSON 对象将返回 object。
// 当为 null 时,JSON 对象将返回关联 array 或 object,这取决于是否在 flags 中设置 JSON_OBJECT_AS_ARRAY
// https://www.php.net/manual/zh/function.json-decode.php
$json = '{"a":1,"b":2}';
var_dump(json_decode($json, null, 512, JSON_OBJECT_AS_ARRAY));
// PHP72
// array(2) {
//   ["a"]=>
//   int(1)
//   ["b"]=>
//   int(2)
// }
//
// PHP71
// object(stdClass)#1 (2) {
//   ["a"]=>
//   int(1)
//   ["b"]=>
//   int(2)
// }

PHP7.2 to PHP7.3

https://www.php.net/manual/en/migration73.php https://php.watch/versions/7.3 Heredoc/nowdoc syntax improvements and a bunch of legacy code deprecations.

New Features 7.3

代码语言:javascript复制
// Heredoc Nowdoc 不再需要后跟分号或换行符
// 结束标记可以缩进,结束时所引用的标识符必须在该行的第一列
$values = [<<<END
a
  b
    c
END, 'd e f'];
var_dump($values);
// PHP73
// array(2) {
//   [0]=>
//   string(13) "a
//   b
//     c"
//   [1]=>
//   string(5) "d e f"
// }
//
// PHP72
// Parse error: syntax error, unexpected end of file

echo <<<END
      a
     b
    c
    END;
// PHP73
//   a
//  b
// c
//
// PHP72
// Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN)

echo <<<END
  a
 b
c
   END;
// PHP73
// Parse error: Invalid body indentation level
代码语言:javascript复制
// 数组解构支持引用赋值
$arr = [[1], [1]];
[&$a, $b] = $arr;
$a[] = 2;
$b[] = 3;
var_dump($arr);
// PHP73
// array(2) {
//   [0]=>
//   &array(2) {
//     [0]=>
//     int(1)
//     [1]=>
//     int(2)
//   }
//   [1]=>
//   array(1) {
//     [0]=>
//     int(1)
//   }
// }
//
// PHP72
// Fatal error: [] and list() assignments cannot be by reference
代码语言:javascript复制
// 允许将 literals 作为第一个操作数,always false
var_dump(true instanceof stdClass);
// PHP73
// bool(false)
//
// PHP72
// Fatal error: instanceof expects an object instance, constant given
代码语言:javascript复制
// 调用中允许尾随逗号
function my($v) {
    echo "php-{$v}";
}
my(73,);
// PHP73
// php-73
//
// PHP72
// Parse error: syntax error, unexpected ')'

New Functions 7.3

代码语言:javascript复制
// Gets the first key of an array
array_key_first(array $array): int|string|null
// Gets the last key of an array
array_key_last(array $array): int|string|null
// Get the system's high resolution time
// [seconds, nanoseconds] int(64 位平台)或 float(32 位平台)
hrtime(bool $as_number = false): array|int|float|false
// 验证变量的内容是否为 countable 值
// return is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXmlElement;
is_countable(mixed $value): bool

Backward Incompatible Changes 7.3

代码语言:javascript复制
// Continue Targeting Switch 问题警告
$foo = 0;
while ($foo < 10) {
    switch ($foo) {
      case "baz":
         continue;
   }
   $foo  ;
}
// PHP73
// Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?
//
// PHP72
// ok
代码语言:javascript复制
// $obj["123"] 类型的数组访问,其中 $obj 实现 ArrayAccess 且 "123" 是整数字符串文字将不再导致隐式转换为整数
// 数组的行为不会受到任何影响,它们继续将整数字符串键隐式转换为整数
class A implements ArrayAccess
{
    public function offsetExists($offset)
    {
    }
    public function offsetGet($offset)
    {
        var_dump($offset);
    }
    public function offsetSet($offset, $value)
    {
    }
    public function offsetUnset($offset)
    {
    }
}
$a = new A();
$a["123"];
// PHP73
// string(3) "123"
//
// PHP72
// int(123)

– EOF –

  • # php

0 人点赞