php5代码升级到php7
PHP 7 发布那年,码升我手上一个跑了六年的码升老项目正好要加新功能。代码是码升 PHP 5.3 写的,里面塞满了 最直接的码升冲击来自被删掉的扩展。PHP 7 干掉了 另一个坑是错误处理。PHP 5 里很多函数遇到错误只返回 语法层面的变化倒不算太痛。PHP 7 新增了标量类型声明和返回类型声明,但你不写也不会报错。真正要留意的是 性能提升是实打实的。同一个接口,PHP 5.6 下平均响应 120ms,切到 PHP 7.0 直接降到 45ms。没改任何代码,只是换了运行时。这让我更有动力去清理那些老扩展。后来我把项目里所有 升级前建议跑一遍 PHP 7 的兼容性检查工具,比如 PHPCompatibility。它能扫出大部分被移除的函数和语法问题。但工具不是万能的,像 还有个小细节:PHP 7 的 最后说个实际案例。一个朋友的公司把电商后台从 PHP 5.6 升到 7.2,结果订单导出功能挂了。原因是代码里用了 mysql_* 函数和 ereg 正则。码升当时没多想,码升直接上了 PHP 7.0 环境,码升结果页面白屏一片。码升查日志才发现,码升mysql_connect() 已经被移除了。码升这不是码升个例,很多 PHP 5 时代的码升代码在 PHP 7 下根本跑不起来。mysql、码升ereg、码升mssql、码升sybase_ct 这些老家伙。你如果还在用 mysql_query() 拼 SQL,升级时就必须换成 mysqli 或 PDO。我当时的做法是用 mysqli 快速替换,因为改动量小——把 mysql_connect 换成 mysqli_connect,mysql_query 换成 mysqli_query,但参数顺序和返回值处理有细微差别。比如 mysqli_query 要求连接对象作为第一个参数,而老函数是资源。这些细节不处理,代码照样崩。false 并抛个警告,PHP 7 把不少情况改成了抛 Error 异常。比如 file_get_contents() 在文件不存在时,PHP 5 给个 warning 然后返回 false,PHP 7 依然如此。但像 call_user_func 调用不存在的函数,PHP 7 会直接抛 Error,而不是返回 false。我有个同事的代码里写了 if (call_user_func($callback) === false),升级后直接 500。改成 try-catch 才解决。foreach 的引用行为。PHP 5 里 foreach ($arr as &$v) 之后,$v 还留着最后一个元素的引用,再循环一次就出诡异 bug。PHP 7 改了这个行为,但如果你代码里依赖旧行为,升级后逻辑就变了。我见过一个统计脚本,因为 foreach 引用没 unset,在 PHP 7 下数据全错。修复方法很简单:循环结束后 unset($v),但找这个问题花了两小时。mysql_* 替换成 PDO,用预处理语句重写了三十多个查询。过程枯燥,但 SQL 注入风险也一并解决了。foreach 引用这种运行时行为,它查不出来。最好还是把项目在 PHP 7 环境里跑一遍完整测试,单元测试覆盖率低的话,就手动点一遍主要功能。我当时的项目没有单元测试,靠的是把日志级别调到 E_ALL,然后挨个页面访问,看错误日志里有没有 Deprecated 或 Fatal。E_STRICT 被移除了,但 E_DEPRECATED 还在。有些老代码用了 mysql_escape_string(),这个函数在 PHP 5.5 就废弃了,PHP 7 直接删除。如果你只是把报错级别调低,这些废弃警告会被忽略,但函数已经不存在了。所以别偷懒,该替换的必须替换。each() 函数,PHP 7.2 标记为废弃,7.3 移除。他们没看更新日志,直接升到 7.2 后功能还能用,但日志里全是废弃警告。后来升 7.3 就彻底报错。所以升级不是一次性的,要跟着 PHP 的小版本走,每个版本都读一遍迁移指南。PHP 7 系列从 7.0 到 7.4,废弃和移除的东西不少,别指望一步到位。
-
上一篇
-
下一篇
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-