命令行执行正常但网页访问报错,说明问题出在Web服务器与ThinkPHP协作环节:需确认DocumentRoot指向public/、重写规则适配FastCGI、php.ini中cgi.fix_pathinfo=0、runtime目录对Web用户可写,并排除.user.ini或中间件导致的响应中断。

命令行执行正常但网页访问报错,说明 PHP 环境本身可用,问题出在 Web 服务器(Apache/Nginx)与 ThinkPHP 的协作环节。核心矛盾是:CLI 模式下路径、配置、权限都走本地上下文;而 Web 请求经过路由重写、请求头传递、FastCGI 处理等多层中介,任一环节偏差都会导致“找不到文件”“权限拒绝”“CORS 失败”或“No input file specified”这类典型表现。
检查 Web 服务器是否真正把请求交给了 index.php
这是最常见也最容易忽略的一环。ThinkPHP 是单入口框架,所有 HTTP 请求必须由 public/index.php 统一接管。若 Apache/Nginx 没正确转发,请求可能被当作静态资源处理,或直接 404。
- 确认 DocumentRoot 指向的是项目 public/ 目录,不是根目录或 application/
- Apache 下检查 .htaccess 是否生效:确保 AllowOverride All 已启用,且 mod_rewrite 已加载
- Nginx 下检查是否配置了正确的 try_files 规则,例如:try_files $uri $uri/ /index.php?$query_string;
- 临时在 public/index.php 开头加
file_put_contents('/tmp/webtest.log', "hit\n", FILE_APPEND);,访问网页后看日志是否有记录——没记录就说明请求根本没进入口文件
验证 FastCGI 路径解析是否适配重写规则
Web 请求走的是 FastCGI(如 php-fpm),它对 PATH_INFO 和 QUERY_STRING 的处理逻辑与 CLI 完全不同。很多 .htaccess 中看似正常的重写,在 FastCGI 下会丢失脚本路径,直接触发 “No input file specified”。
- 检查 .htaccess 中的 RewriteRule:错误写法
RewriteRule ^(.*)$ /index.php/$1 [L]会导致 FastCGI 无法识别真实脚本;应改为RewriteRule ^(.*)$ /index.php?/$1 [L]或更稳妥的RewriteRule ^(.*)$ /index.php [L,E=PATH_INFO:$1] - 确认 RewriteBase 设置与实际部署路径一致(如部署在
/blog/子目录,就要写RewriteBase /blog/) - 检查 php.ini 中 cgi.fix_pathinfo 是否为 0(设为 1 时 FastCGI 会做路径猜测,极易引发歧义)
排查 Web 服务器级权限与路径干扰
CLI 用户(如当前登录用户)和 Web 服务用户(如 www-data、apache)拥有完全不同的文件系统权限和环境变量,.user.ini、open_basedir、doc_root 等配置在 Web 模式下才起作用。
立即学习“PHP免费学习笔记(深入)”;
- 检查 public/ 及其子目录(尤其是 runtime/)是否对 Web 用户可读可写(常见于 macOS 或 Linux 权限未放开)
- 临时重命名项目根目录下的 .user.ini(如改为 .user.ini.bak),重启 Apache/Nginx 测试是否恢复——若恢复,说明其中的 open_basedir 或 auto_prepend_file 配置限制了 Web 访问路径
- 确认 php.ini 中没有硬编码 doc_root,该设置会强制限定脚本根目录,导致 Web 请求路径映射失败
确认跨域与中间件链是否意外中断
部分报错(如 CORS header missing、空白页、跳转到登录页)并非底层执行失败,而是响应阶段被拦截或覆盖。尤其在开启调试模式或使用中间件时,Web 请求会完整走完中间件管道,而 CLI 不走这一套。
- 检查 app/middleware.php 是否将 think\middleware\Cors 正确注册为全局中间件(注意类名不是 CorsMiddleware)
- 查看控制器中是否存在提前 return json()、exit 或 $this->error() ——这会让后续中间件(包括 Header 注入)不再执行
- 用浏览器开发者工具 Network 面板查看响应状态码和响应头:返回 302?说明被重定向到了 login;返回 500?查 Web 服务器错误日志(如 Apache 的 error_log);返回 200 但内容为空?可能是模板路径错误或 fetch() 找不到视图文件



















