上周把博客服务器的PHP从7.4升到了8.5,本来以为就是改个版本号的事,结果折腾了整整两天。
其实早该升了。PHP 7.4早就停止安全更新,每次看到后台提示版本过旧都心里发虚。但一直拖着,就是怕出问题——老代码自己写的,心里有数,能跑就行,动它干嘛。
这次下定决心升级,是因为要做视频代理接口。新写的代码用了PHP 8的枚举和命名参数,本地跑着挺爽,一传到服务器直接报错,才发现服务器还停在7.4。那就升吧。
缓存反序列化失败
升完之后打开首页,直接白屏。报错信息很眼熟:unserialize(): Error at offset 0 of 1 bytes in core/cache.php on line 88。
查了半天才想明白。PHP 8.1以后对序列化数据的校验更严格了,以前缓存里存的那些乱七八糟的字符串,以前能容错就过了,现在直接不认。解决办法倒简单,把缓存目录清空就行。
这就是老代码的问题——当初写缓存的时候图省事,直接serialize()丢进去,连个版本号都不带。以后再升级,还得踩这个坑。
curl_close废弃警告
页面能打开之后,顶部开始飘一堆Warning。都是同一个问题:Function curl_close() is deprecated since 8.5。
我翻了一下代码,好家伙,全站到处都是curl_close()。OAuth登录、B站解析、AI接口、一言API……十几个文件,每个都写了$ch = curl_init(),用完curl_close()。
后来查了PHP升级文档才知道,从PHP 8.0开始,curl_close()已经没实际作用了——curl句柄会自动释放。保留它纯粹是为了向后兼容,所以8.5直接给了个废弃警告。
改法也简单,把所有curl_close()换成unset($ch)就行。但十几个文件挨个改也挺烦的。最后干脆把所有curl调用封装成了一个http_request()函数,以后不用再写一堆重复的curl代码。
这事儿其实也暴露了一个问题:项目越做越大,代码越攒越多,早就该重构了。但一直"还能跑就别动",最后越攒越乱。
类型严格了,以前的小问题全暴露
最头疼的还是类型问题。PHP 7.4的时候,类型不匹配最多给个Notice,页面照常跑。到了8.5,很多以前的隐式转换直接变成Warning,甚至直接报错。
比如那个ICO生成类,本来是计算图片尺寸的,以前float转int直接截断,现在给个"implicit conversion from float to int loses precision"的警告。虽然不影响结果,但警告一多,连带着后面的header()都发不出去——因为前面已经输出了警告内容。
这种问题最麻烦。它不是报错,就是飘在那里,让你觉得浑身难受,但又不影响功能。你得一个个找,一个个改。
升级前的准备工作
踩完这些坑之后,我总结了几点经验:
- 升级前先把错误报告全开,把本地PHP 8.5跑一遍,所有Notice和Warning都处理掉再上线
- 序列化的数据,升级前先清缓存,别舍不得那点缓存
- 老的curl代码趁早封装,别东写一块西写一块
- 类型能写明确就写明确,别靠PHP自动转换,早晚有一天会出问题
其实升级这事儿,就像收拾房间。平时看着乱,凑合着也能住,但真要彻底整理一次,才发现角落里藏了多少东西。
现在升完了,PHP 8.5跑起来确实快了不少,类型系统严格了之后,写代码反而更踏实了——以前靠运气不出bug,现在编译器帮你查。
唯一的代价就是,这两天改代码改得手酸。但想想以后不用再对着7.4写代码,值了。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录