必须先升到PHP 7.4,因它是唯一既兼容PHP 5.6语法又主动报告E_DEPRECATED警告的版本,能提前暴露mysql_*、create_function()等PHP 8将彻底移除的用法,避免直接升级导致Fatal error。

不能直接从 PHP 5.6 升到 PHP 8,中间必须经过 PHP 7.4 过渡。跳步升级会漏掉所有 E_DEPRECATED 警告,导致上线后大量 Fatal error 或行为异常,比如 count(null) 突然报错、mysql_connect() 彻底消失、each() 返回 false 而不是数组。
为什么必须先升到 PHP 7.4?
PHP 7.4 是唯一一个既保留全部 PHP 5.6 兼容语法、又主动提示废弃用法的版本。它会把所有 PHP 8 里要炸的地方提前标出来:
-
mysql_*函数调用 → 日志里出现Deprecated: mysql_connect(): The mysql extension is deprecated -
create_function()→ 报Deprecated: Function create_function() is deprecated -
eregi()、split()→ 同样触发Deprecated警告 - 未初始化变量直接
echo $undefined→ 在 PHP 7.4 默认不报错,但开启error_reporting = E_ALL | E_DEPRECATED就能捕获
这些警告就是 PHP 8 的“死亡预告”。没它们,你等于蒙眼跳崖。
PHP 7.4 过渡期实操三件事
装好 PHP 7.4 后别急着改代码,先做这三步验证:
立即学习“PHP免费学习笔记(深入)”;
- 在入口文件(如
index.php)顶部加error_reporting(E_ALL | E_DEPRECATED); ini_set('display_errors', '1');,跑完整站流程(含后台、API、定时任务) - 用
php -l批量扫描所有 PHP 文件:find . -name "*.php" -exec php -l {} \; 2>&1 | grep "Errors parsing",揪出语法级硬伤(比如 PHP 5.6 允许的function foo($a = [])在 PHP 7.4+ 若声明为array类型却传null,会直接失败) - 检查
phpinfo()输出里的Loaded Configuration File,确认date.timezone已显式设置(PHP 7.4 不再容忍未设时区,否则date()、strtotime()可能返回空或警告)
哪些函数和写法必须立刻替换?
以下高频出问题点,改完才能进 PHP 8:
-
mysql_connect()/mysql_query()→ 改用PDO或mysqli;注意mysql_real_escape_string()没有等价物,必须用预处理($stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?")) -
each()→ 全部删掉,统一改成foreach ($arr as $k => $v),别再依赖内部指针 -
count($data)→ 前面加判空:is_array($data) || is_object($data) ? count($data) : 0(PHP 8 对null、string直接抛TypeError) -
create_function()→ 改成匿名函数,例如array_map(function($v) { return $v * 2; }, $arr);别用eval()替代 -
eregi()/split()→ 改用preg_match("/pattern/i", $str),注意正则分隔符和修饰符位置
vendor 和扩展怎么处理?
PHP 版本一变,vendor/ 就失效:
- 删掉整个
vendor/和composer.lock - 更新
composer.json里的"php": "^7.4",然后运行composer install - 检查
php -m输出,确认openssl、mbstring、curl都在,mcrypt必须换成openssl_encrypt()(IV 长度、填充方式、密钥派生逻辑全不同) - Apache 用户重点看
httpd.conf里LoadModule php_module路径是否指向 PHP 7.4 目录;Nginx 用户确认fastcgi_pass指向的是php7.4-fpm的 socket 或端口(不是默认的:9000)
真正难的不是改代码,是那些没打日志的隐式依赖——比如某个老插件靠 register_globals 活着,或者某段 SQL 拼接逻辑在 PHP 8 的 strict_types 下因字符串转 int 失败而静默崩掉。过渡期一定要开全量日志,盯紧错误发生前的上下文。



















