上周公司终于下定决心将维护了10年之久的老项目从php5.6升级至php7.4,虽然现在最新的php8.2都发布了,但出于php8对比php5在写法有较大的差异性考虑,退而求其次的选择了php7.4。这对于老项目来说,仍然也是一种巨大的进步。
-
在将项目升级至php7.4版本后,开始对代码进行语法检查。
-
明面上的语法错误,比如 array_key_exists()函数废弃使用,大括号访问数组和字符串索引的用法。这种错误可以使用phpstorm编辑器中的检查代码功能,对所有的php文件都扫描一遍,有错误的改了就行。具体操作方法如图所示:
-
底子里的错误,不好发现,往往需要测试一下才能发现。
下面聊一聊几点我在修改代码过程中发现的一些比较隐蔽的问题:
- 问题一:不能直接使用字符串数组中的元素来调用类方法或类属性。
<?php
class classA
{
public function printf()
{
echo 'This is printf';
}
}
$arr = [
'class' => 'classA',
'func' => 'printf'
];
$obj = new $arr['class'];
$obj->$arr['func']();
运行结果:
**Notice**: Array to string conversion in **D:\SoftApp\PHPServer\www\index.php** on line **17**
**Notice**: Undefined property: classA::$Array in **D:\SoftApp\PHPServer\www\index.php** on line **17**
**Notice**: Trying to access array offset on value of type null in **D:\SoftApp\PHPServer\www\index.php** on line **17**
**Fatal error**: Uncaught Error: Function name must be a string in D:\SoftApp\PHPServer\www\index.php:17 Stack trace: #0 {main} thrown in **D:\SoftApp\PHPServer\www\index.php** on line **17**
从错误提示可以看出,在第17行 $obj->$arr[‘func’]竟然说是null值。
规避做法:
$obj = new $arr['class'];
$obj->{$arr['func']}(); //添加大括号符
//运行结果:
This is printf
- 问题二:构造函数中存在非可选参数,实例化时必须传入
<?php
class classB
{
public function __construct($name){}
}
$obj = new classB();
运行结果:
**Fatal error**: Uncaught ArgumentCountError: Too few arguments to function classB::__construct(), 0 passed in D:\SoftApp\PHPServer\www\index.php on line 8 and exactly 1 expected in D:\SoftApp\PHPServer\www\index.php:5 Stack trace: #0 D:\SoftApp\PHPServer\www\index.php(8): classB->__construct() #1 {main} thrown in **D:\SoftApp\PHPServer\www\index.php** on line **5**
虽然正常场景下,大多数人不会不传入初始化参数。 但在php5.6中,有较大的包容性,并不会强制性要求你。我在检查过往历史代码时,也的确发现不少这种不规范的代码。