Laravel应用部署后出现'unexpected '?'语法错误如何排查?
解决Laravel 5.4部署至PHP 7.0虚拟主机的语法错误问题
嘿,这个Parse error: syntax error, unexpected '?'的问题我太熟了,大概率是语法版本不兼容搞的鬼,咱们一步步拆解:
核心原因
虽然Laravel 5.4官方标注最低支持PHP 7.0,但你遇到的这个错误,几乎可以确定是代码里用了PHP 7.1及以上才有的语法特性——比如可为null的类型声明(像function test(?string $name)这种带?的写法),而你的主机是PHP 7.0,根本认不出这种语法。
最常见的触发场景是:你在本地用PHP 7.1+的环境装了依赖(执行了composer install/update),然后直接把本地的vendor目录传到了主机。Composer会根据本地PHP版本拉取适配的依赖包,这些依赖早就用上了7.1的语法,放到7.0的环境里自然报错。
具体解决步骤
别传本地的
vendor,在主机重新装依赖- 先把本地项目里的
vendor和.env删掉,只上传其他源代码到主机。 - 如果主机支持SSH,登录后进入项目根目录,执行这条命令:
这样Composer会根据主机的PHP 7.0环境,拉取完全兼容的依赖包,从根源避免语法冲突。composer install --no-dev --optimize-autoloader
- 先把本地项目里的
检查
composer.json的版本约束- 打开项目的
composer.json,确保require里的PHP版本约束是>=7.0.0,别不小心写成了>=7.1。另外,看看有没有第三方扩展强制要求PHP 7.1+,如果有,得给它指定兼容7.0的版本,比如:
改完后在主机重新跑"require": { "php": ">=7.0.0", "some/package": "^2.0" // 确认这个版本支持PHP7.0 }composer update。
- 打开项目的
自查自定义代码
- 如果你自己写的代码里用了7.1的特性(比如带
?的类型声明),得改成7.0兼容的写法:- 比如把
function getUserName(?int $userId)改成function getUserName($userId),然后在函数里手动判断$userId是不是null。
- 比如把
- 如果你自己写的代码里用了7.1的特性(比如带
确认主机的真实PHP版本
- 有时候主机面板显示的版本和实际运行的不一样,你可以在项目根目录建个
phpinfo.php,内容如下:
访问这个页面,确认实际运行的PHP版本确实是7.0.x,避免被面板显示坑了。<?php phpinfo(); ?>
- 有时候主机面板显示的版本和实际运行的不一样,你可以在项目根目录建个
额外建议
如果主机允许升级PHP版本,直接升到7.1及以上最好——Laravel 5.4最高支持到PHP7.3,升级后不仅能解决这个问题,性能和安全性也会更好。
内容的提问来源于stack exchange,提问作者Stephany Rocks
相关产品推荐
相关产品推荐

