Ubuntu 下调试 PHP,最怕的不是报错本身,而是没有顺序地四处排查。更稳妥的做法,是先确认错误出现在哪一层,再决定用日志、浏览器报错还是 Xdebug 继续深入。按本文这套路径走,你可以较快判断问题究竟出在 Web 服务器、PHP 配置、调试工具,还是文件权限与扩展依赖上。
先从错误日志入手,确定报错出现在哪一层
PHP 出错时,最直接的线索通常就在日志里。相比反复猜配置或改代码,先盯住日志输出,往往能更快确认是语法错误、运行时异常,还是服务层面的调用失败。
Apache 环境看哪里
如果你的 PHP 跑在 Apache 下,优先查看错误日志 /var/log/apache2/error.log:
sudo tail -f /var/log/apache2/error.log
这个命令会持续输出最新日志,适合一边刷新页面一边观察错误是否同步出现。
Nginx 环境看哪里
如果前端是 Nginx,对应的错误日志通常在 /var/log/nginx/error.log:
sudo tail -f /var/log/nginx/error.log
当请求没有正确转发到 PHP,或者上游响应异常时,这里通常会先给出提示。
使用 PHP-FPM 时别漏看进程日志
如果站点通过 PHP-FPM 处理 PHP,请继续检查 FPM 日志。常见路径包括 /var/log/php-fpm.log 或 /var/log/php7.x-fpm.log,其中 x 代表你的 PHP 版本号。
查看方法同样可以直接用 tail。如果 Web 服务器日志信息不完整,而请求又确实落到了 PHP,这一步通常能补上关键细节。
开发环境下开启错误显示,直接看浏览器输出
日志能帮你定位大方向,但在开发环境里,直接把错误显示到页面上会更高效。尤其是语法错误、未定义变量、函数调用失败这类问题,浏览器往往能给出更明确的文件和行号。
临时开启:适合快速测试当前脚本
如果只是临时排查某个脚本,可以在文件开头加入以下代码:
<?php
ini_set('display_errors', 1); // 开启错误显示
error_reporting(E_ALL); // 报告所有类型错误(包括Notice、Warning、Fatal Error)
?>
这种方式只对当前脚本生效,适合快速验证,不会长期影响整站配置。
永久开启:修改 php.ini 更适合持续开发
如果你需要在本地或测试环境持续查看错误,直接修改 php.ini 更省事。
先用下面的命令确认配置文件路径:
php --ini
例如,你可能会看到类似 /etc/php/8.2/apache2/php.ini 的路径。
随后用编辑器打开文件,把以下配置调整到位:
display_errors = On # 开启错误显示
error_reporting = E_ALL # 报告所有错误
log_errors = On # 同时记录错误到日志(避免丢失)
error_log = /var/log/php_errors.log # 自定义日志路径(可选)
修改完成后,需要重启对应服务:
Apache:
sudo systemctl restart apache2
Nginx + PHP-FPM:
sudo systemctl restart php8.2-fpm && sudo systemctl restart nginx
这里的 php8.2-fpm 要与实际安装版本保持一致。
需要断点和调用栈时,再上 Xdebug
日志和页面报错,解决的是“哪里出问题了”;而 Xdebug 更适合回答“为什么会这样”。当你需要单步执行、观察变量变化、分析调用链时,Xdebug 才是真正的主力工具。

先安装 Xdebug 扩展
Ubuntu 仓库里通常已经提供 Xdebug,直接安装即可:
sudo apt-get install php-xdebug
再补齐调试配置
安装后,编辑 php.ini,加入或核对以下配置。注意其中 zend_extension 的实际加载方式要与本机 PHP 版本匹配:
zend_extension=xdebug.so # 加载Xdebug扩展
xdebug.remote_enable=1 # 开启远程调试
xdebug.remote_host=localhost # 调试客户端地址(本地为localhost)
xdebug.remote_port=9003 # 调试端口(默认9003,避免与其它服务冲突)
xdebug.remote_handler=dbgp # 调试协议
xdebug.remote_autostart=1 # 自动启动调试(无需手动触发)
xdebug.idekey=PHPSTORM # IDE标识(如PHPStorm、VSCode)
这组配置的目标很明确:让 PHP 在执行时能够主动把调试信息发给本地 IDE。
以 PHPStorm 为例完成 IDE 映射
如果 IDE 侧没有正确配置,Xdebug 即使加载成功,也可能无法在断点处停下来。以 PHPStorm 为例,基本步骤如下:
- 进入
File > Settings > Languages & Frameworks > PHP > Servers,点击+添加服务器。 - 设置
Name(例如Local),Host填localhost,Port填80,并勾选Use path mappings。 - 把项目目录映射到服务器路径,例如将
/var/www/html对应到本地项目根目录。 - 点击
Run > Start Listening for PHP Debug Connections,然后在代码里设置断点并刷新浏览器。
如果浏览器请求已经到达 PHP,但 IDE 不停在断点上,优先检查路径映射和端口设置是否一致。
遇到 Permission Denied,优先检查权限和所有权
很多 PHP 报错并不是代码逻辑问题,而是进程根本读不到、写不了或者执行不了目标文件。这类错误通常会表现为 Permission Denied、上传失败、缓存目录不可写等。
先确认文件归属用户
在 Ubuntu 上,Web 服务器常见运行用户是 www-data。如果项目目录归属不对,可以调整为:
sudo chown -R www-data:www-data /path/to/your/php/files
再把目录和文件权限拆开处理
目录通常需要可进入权限,文件则只需正常读取。常见做法是目录 755、文件 644:
sudo chmod -R 755 /path/to/your/php/files
sudo find /path/to/your/php/files -type f -exec chmod 644 {} \;
如果只是简单递归改成同一权限,往往会把文件和目录混在一起处理,后续反而更难排查。
最后验证配置与扩展是否真正生效
改完配置、装完扩展后,不要只看命令是否执行成功,还要确认运行中的 PHP 进程已经加载了正确设置。

用 phpinfo() 检查当前配置
创建一个 info.php 文件,内容如下:
<?php phpinfo(); ?>
通过浏览器访问后,可以直接确认 display_errors、error_reporting 等配置是否已经生效,也能看到当前加载的模块和配置文件路径。
缺扩展时按报错安装对应模块
如果日志或页面提示缺少扩展,例如 mbstring、gd,就按需安装:
sudo apt-get install php-mbstring php-gd # 根据错误提示替换扩展名
sudo systemctl restart apache2/nginx/php-fpm # 重启服务使扩展生效
这里的扩展名应以实际错误提示为准,不需要一次装一大批无关模块。
上线前还要收尾三件事
开发环境能看到详细错误,不代表生产环境也该这样配置。正式上线前,至少把下面三点再核对一遍。
1. 关闭生产环境的 display_errors
生产环境应将 display_errors 设为 Off,避免把路径、配置、SQL 片段等敏感信息直接暴露给访问者。线上环境保留日志记录即可。
2. 处理日志轮转
错误日志会持续增长,建议通过 logrotate 定期清理,避免日志文件长期膨胀占满磁盘。
3. 核对 PHP 版本兼容性
应用本身也可能对 PHP 版本有硬性要求。例如 Laravel 10 需要 PHP 8.1 及以上。可以先执行:
php -v
确认当前运行版本,再和项目要求逐项对照,避免把兼容性问题误判成普通报错。













