PHP 7.3“Permission denied”是操作系统拒绝访问,需依次确认Web进程用户(如www-data)、逐级检查目录x权限、验证文件属主与644/755权限、排查SELinux/AppArmor及PHP-FPM pool配置一致性。

PHP 7.3 项目运行时提示“Permission denied”,不是代码写错了,而是操作系统拒绝了文件读写——哪怕路径完全正确、文件真实存在,只要 Web 进程用户(如 www-data)对目标路径没有对应权限,就会直接报错并中断执行。
确认 PHP 实际运行用户
第一步必须搞清“谁在操作文件”。PHP 7.3 在 Apache 或 Nginx 下运行时,身份由 Web 服务器进程决定,不是你登录系统的账号,也不是 root。
新建一个 whoami.php 文件,内容为:<?php echo exec('whoami'); ?>,通过浏览器访问它。若返回为空或报错,改用 <?php echo posix_getpwuid(posix_geteuid())['name']; ?>(需启用 posix 扩展)。
终端中执行 ps aux | grep -E '(apache|httpd|nginx|php-fpm)',观察主进程的 USER 列,例如看到 www-data 12345 ... /usr/sbin/apache2,就确认用户是 【www-data】。
立即学习“PHP免费学习笔记(深入)”;
这一步跳过会导致后续所有权限修改都无效——你可能正把权限赋给 apache,而实际运行的是 php-fpm 用户。
逐级检查目录执行权限
Web 服务器要打开 /var/www/myapp/config/db.php,必须能“走进去”每一层:/var → /var/www → /var/www/myapp → /var/www/myapp/config。缺任一目录的 x(执行)位,就卡在半路。
执行:ls -ld /var /var/www /var/www/myapp /var/www/myapp/config
重点看每行权限字段第4、7、10位(对应 user/group/others 的 x),若某层显示 drw-r--r--(无 x),则该目录无法被遍历,直接导致“failed to open stream: Permission denied”。
修复命令:sudo chmod 755 /var/www/myapp/config。注意:不要对 /var 或 /var/www 盲目加 x,它们通常已有;只修正你项目所在路径及子目录。
验证关键文件的读写权限
方法一:用 PHP 函数现场检测
is_readable('/var/www/myapp/config.php') 返回 false?说明 Web 用户连读都不行,可能是文件属主不是 www-data 且权限不足(如 600)。
is_writable('/var/www/myapp/cache/') 返回 false?常见于缓存目录未开放组写或属组不匹配。
方法二:终端直查,更可靠
执行:ls -l /var/www/myapp/config.php,确认第三列(属主)或第四列(属组)是否为 www-data;权限字段应至少为 【644】(文件)或 【755】(目录)。若显示 -rw------- 1 root root,则必须改属主。
执行:sudo chown www-data:www-data /var/www/myapp/config.php → sudo chmod 644 /var/www/myapp/config.php。
排查 SELinux 或 AppArmor 干预
仅限 CentOS/RHEL 等启用强制访问控制的系统。Debian/Ubuntu 默认不启用,可跳过。
先运行 sestatus,若输出为 enabled,再执行 ls -Z /var/www/myapp/config.php。如果上下文类型不是 httpd_sys_content_t(Apache)或 httpd_sys_rw_content_t(需写入),而是 unconfined_u:object_r:user_home_t:s0,说明 SELinux 拦截了。
临时放行测试:sudo chcon -t httpd_sys_content_t /var/www/myapp/config.php。若问题消失,说明是 SELinux 导致——生产环境应写策略规则,而非长期用 chcon。
AppArmor 用户执行 aa-status 查看是否启用,若启用则检查 /etc/apparmor.d/usr.sbin.apache2 是否包含项目路径的读取权限声明。
检查 PHP-FPM 用户与 pool 配置一致性
PHP 7.3 常以 FPM 方式运行,其用户由 pool 配置文件控制,不一定和 Apache/Nginx 主进程一致。
第一步:找到 pool 配置,通常在 /etc/php/7.3/fpm/pool.d/www.conf(Ubuntu)或 /etc/php-fpm.d/www.conf(CentOS)。
第二步:检查其中两行:
user = www-data
group = www-data
若此处是 user = nginx,但你前面一直按 www-data 授权,必然失败。必须统一。
改完配置后,【必须重启 php-fpm 服务】:sudo systemctl restart php7.3-fpm(Ubuntu)或 sudo systemctl restart php-fpm(CentOS)。



















