这是来自2019年的前情提要:将PHP版本从5.6升级到7.3中遇到的坑汇总贴[不定时更新]
提示:这是一篇技术博客,请普通玩家不必关注此文。
总之,随着时代的变化,为了优化网站执行效率,为了实装更多新科技,为了与各种新型框架接轨,在3年前将PHP版本升到7.3之后,今次将再次将其升级到8.1。
目前经过大约一周的密集调试,升级工程已经基本完成(不过只是确认了各种基础功能能正常工作,可能会有各种小功能会导致异常)
因此这是另一份技术留底。希望有同类问题的人能搜到此篇Blog
PHP8不支持从Null,或者未定义变量中执行各种数组/类的操作
最常见的情况是,假设一个数组 $arr = DB::select() blabla这样的操作,但是这个数组并没有从数据库中查询出任何值,接下来如果使用 foreach 或者类似操作,可能会报 invalid argument supplied for foreach() 错误。
(对,是可能,因为有时候不一定会出这个错误,因为历史遗留太多,暂未查明)
另外,对于需要链式调用的对象(例如 blabla()->foo()->bar() 这种)的情况,如果中间有一个返回了null,那么整个链式调用会断掉。需要手动处理。
PS:PHP8中有一个nullsafe写法可以很方便的解决↑上面这个问题,具体可参见PHP官方文档 https://www.php.net/manual/zh/language.oop5.basic.php#language.oop5.basic.nullsafe
解决方案:挨个改吧……写个if !empty 什么的……
除以0现在是Error而不是Warning
如题,现在除以0会直接error报错 division by zero
解决方案:挨个改……
一大票隐式类型转换全部失效
例如:数组的下标只能是数字或者字符串,不能是另一个数组或者对象或者null(以前版本会进行隐式转换)。出现这种错误的话会报错 Illegal offset type
解决方案:挨个改……这个改起来会很痛苦,只能看到一个报错改一个。
常量名无法自动转为对应字符串
旧版本的PHP中,如果一个字符串忘了打引号就使用(这相当于一个常量),那么会自动的将其转为等同于这个常量名的字符串。
举例 foo(aaa);
如果不存在一个名叫aaa的常量,那么等同于 foo(“aaa”);
新版本中这个转换失效,会报错未定义的常量 (Undefined constant)
解决方案:挨个加引号!
create_function 函数被废弃
在旧版本还没有回调函数的之后,create_function可以用于在类似于array_map之类的函数中执行类似于回调函数的功能
新版本中会直接报错 create_function 未定义
解决方案:改为回调函数的模式
implode不再支持分隔符在后,操作变量在前的写法。
参见 https://www.php.net/manual/zh/function.implode.php
虽然我自己没用这种写法,但许多第三方库用了这个,如果这个第三方库不更新,需要手动更新,如果这是个用composer管理的库……那就先无能狂怒一会吧!
解决方案:手动改~
许多函数如果要求一个数组作为参数,如果传入参数不是一个数组,那么会直接报错。
会报类似于 Uncaught TypeError: foo(): Argument #1 ($bar) must be of type array, string given 之类的错误(也有可能是 null given)
没有什么规律,似乎是非常混乱的出现。
解决方案:找到一个改一个。
单例类的方法必须显式指明 public static function
某些第三方库可能会偷懒只写 function 在PHP8中必须要显式标明
解决方案:改改改~
之后有新的还会不定期更新。