Laravel文件上传后404的根本原因是Web服务器DocumentRoot未正确指向public目录,导致请求未经index.php路由处理;正确做法是将DocumentRoot设为public绝对路径并配置AllowOverride All。

直接把 public 目录下的全部文件(含 index.php 和 .htaccess)上传到虚拟主机根目录,再改两处路径定义,基本就能跑通——但多数人卡在静态资源 404、模板找不到、或框架报“require failed”上,本质是入口位置和路径映射没对齐。
为什么不能直接传整个项目包?
ThinkPHP5.0 默认结构里,public 是唯一应被 Web 服务器直接访问的目录;application、thinkphp 等必须对外不可见。虚拟主机通常只开放根目录(如 htdocs 或 www)为 Web 入口,不支持设置 DocumentRoot 到子目录。若整包上传,index.php 就在错误层级,框架无法加载自动加载器,会报:require(): Failed opening required '.../thinkphp/base.php'。
- 阿里云/万网等主流虚拟主机不支持修改 Apache/Nginx 的
DocumentRoot - 你无法启用
mod_rewrite模块,也不能改httpd.conf,只能靠.htaccess和入口文件适配 -
public目录里的index.php是专为这种环境设计的“安全入口”,别绕开它
入口文件要怎么改?
把 public/index.php 复制到虚拟主机根目录(如 /htdocs/index.php),然后编辑它:
// 原始内容(指向上级目录)
define('APP_PATH', __DIR__ . '/../application/');
require __DIR__ . '/../thinkphp/start.php';
// 改为(相对路径向上两级,因入口已下移)
define('APP_PATH', __DIR__ . '/application/');
require __DIR__ . '/thinkphp/start.php';
- 如果框架目录不在根目录同级(比如你把
thinkphp文件夹重命名了),就按实际路径写死,例如require __DIR__ . '/framework/start.php'; - 确保
application和thinkphp目录都和新index.php在同一层,且可读(权限建议 755) - 别删
.htaccess,它必须和index.php同目录,否则路由重写失效,点内页 404
静态资源全挂了怎么办?
原 public 结构中,CSS/JS 图片默认从 /static/ 加载,但现在 index.php 在根,而 static 实际在 /public/static/ —— 所以浏览器请求 /static/css/app.css 会 404。
立即学习“PHP免费学习笔记(深入)”;
- 最稳妥做法:在
config/app.php中加view_replace_str配置:'view_replace_str' => [ '__STATIC__' => '/public/static', '__CSS__' => '/public/static/css', '__JS__' => '/public/static/js', '__IMG__' => '/public/static/images', ], - 模板里所有路径必须用这些常量,例如:
<link href="__CSS__/app.css" rel="stylesheet"> - 特别注意 CSS 文件里的
background: url(../images/logo.png)—— 这种相对路径会失效,得改成url(__IMG__/logo.png)或绝对路径url(/public/static/images/logo.png)
Linux 虚拟主机上模板总找不到?
阿里云等虚拟主机用的是 CentOS,文件系统严格区分大小写。如果你控制器方法叫 userCenter(),对应模板文件名必须是 usercenter.html(全小写),否则 $this->fetch() 找不到。
- 不要依赖方法名自动推导模板,显式指定:
$this->fetch('usercenter') - 检查所有
fetch()、display()调用,确认传入的模板名和磁盘文件名完全一致(包括大小写) - 上传时用 ZIP 打包再解压,避免 FTP 客户端自动转小写导致混乱
最关键的其实是路径对齐:入口在哪,APP_PATH 就得指哪,view_replace_str 就得补哪,模板名就得匹配哪——三者错一个,就断一环。别试图“差不多能跑”,虚拟主机没调试日志,问题往往藏在路径拼接的毫厘之间。



















