【中国观察北京时间2026年08月16日】
很多人开始开发 PHP 网站时,最先接触的是 index.php、css、js、数据库连接和各种 include 文件。网站小的时候,这样做通常没有太大问题,所有文件放在一个网站目录里也能运行。
但随着网站功能增加,问题很快就会出现:数据库配置文件放在哪里?后台程序应该放在哪里?上传的图片放在哪里?日志放在哪里?哪些文件可以直接通过浏览器访问,哪些文件应该放在网站公开目录之外?
真正理解这些问题,需要先弄清楚一个最基本的概念:服务器上的项目目录,和浏览器能够访问的 Web 根目录,并不是一回事。
Web 根目录到底是什么
Apache 和 Nginx 都会把网站请求映射到服务器上的文件。
以 Apache 为例,DocumentRoot 定义了网站的基本文档目录。假设某个网站的 DocumentRoot 是:
/var/www/example/public
那么访问:
https://example.com/index.php
对应的文件通常就是:
/var/www/example/public/index.php
Apache 官方文档也明确说明,DocumentRoot 下的文件和目录构成网站可以通过 Web 访问的基本文档树。
Nginx 的思路类似,只不过使用的是 root 等配置指令来指定请求对应的文件系统目录。
因此,不要把 /var/www/html、htdocs、public_html 或 public 理解成 PHP 固定规定的目录名称。
它们只是不同服务器、主机环境或者项目习惯中的目录名称。
真正重要的是:
服务器到底把哪个目录设置成了 Web 根目录。
为什么很多 PHP 项目会单独设置 public 目录
一个比较合理的 PHP 项目结构可以是:
mywebsite/
├── app/
├── config/
├── storage/
├── vendor/
├── database/
├── public/
│ ├── index.php
│ ├── css/
│ ├── js/
│ └── images/
└── composer.json
然后把 Web 服务器的根目录设置成:
mywebsite/public/
这样,浏览器能够直接访问的主要是 public 里面的内容。
例如:
https://example.com/
对应:
mywebsite/public/index.php
而:
mywebsite/config/
虽然存在于服务器上,却不应该成为普通网页可以直接访问的目录。
这种结构的好处非常直接:把必须公开给浏览器的文件,与程序内部文件分开。
PHP 官方文档也特别提醒,把脚本等活动内容直接放在 Web 文档目录中可能增加信息泄露风险;如果服务器配置错误导致 PHP 文件没有被执行而是作为普通文件提供,就可能暴露源代码甚至敏感信息。
public 里面应该放什么
如果采用这种结构,public 应该尽量保持简单。
例如:
public/
├── index.php
├── css/
├── js/
├── images/
├── favicon.ico
└── robots.txt
这里的文件通常属于网站前端需要直接获取的资源。
index.php 可以作为网站入口。
CSS、JavaScript、图片、字体等静态资源也可以放在这里。
如果使用前端构建工具,最终需要提供给浏览器的静态文件也通常会进入这个公开目录。
核心原则不是目录名称必须叫 public,而是:
Web 根目录应该只放真正需要通过 HTTP 提供给用户的文件。
app 目录放什么
app 可以理解成网站真正的业务代码。
例如:
app/
├── Controllers/
├── Models/
├── Services/
└── Helpers/
一个新闻网站可能有:
app/
├── Controllers/
│ ├── ArticleController.php
│ ├── SearchController.php
│ └── UserController.php
├── Models/
│ ├── Article.php
│ └── User.php
└── Services/
└── ArticleService.php
这里的具体划分没有唯一标准。
小网站甚至完全可以没有 Controllers、Services 这些目录。
重要的是不要把所有代码都堆到一个 index.php 里面。
当一个 PHP 文件同时负责数据库查询、用户权限判断、HTML 输出、文件上传和业务处理时,后期维护会非常困难。
config 目录应该放什么
配置文件通常包括:
config/
├── database.php
├── app.php
└── mail.php
例如数据库服务器地址、数据库名称、用户名、密码等,都属于配置内容。
如果配置文件包含密码、API Key 等敏感信息,就不应该把它们作为公开网页资源保存。
更合理的项目结构是让 config 位于 Web 根目录之外:
mywebsite/
├── config/
│ └── database.php
└── public/
└── index.php
然后从程序内部加载:
require __DIR__ . '/../config/database.php';
这里使用 __DIR__ 的好处,是路径以当前 PHP 文件所在目录为基准,而不是依赖服务器当前工作目录。
PHP 官方文档提供的路径相关机制也支持使用 __DIR__ 获取当前文件所在目录。
不要把 DOCUMENT_ROOT 当成整个项目目录
这是 PHP 初学者非常容易弄混的地方。
例如:
$_SERVER['DOCUMENT_ROOT']
得到的是服务器配置中的 Web 根目录。
PHP 官方定义中,DOCUMENT_ROOT 指的是当前脚本所在网站的 document root。
假设实际项目是:
/home/user/mywebsite/
├── config/
├── app/
└── public/
└── index.php
而服务器设置:
DocumentRoot = /home/user/mywebsite/public
那么:
$_SERVER['DOCUMENT_ROOT']
得到的就是:
/home/user/mywebsite/public
而不是:
/home/user/mywebsite
因此,如果你写:
require $_SERVER['DOCUMENT_ROOT'] . '/config/database.php';
程序实际上会寻找:
/home/user/mywebsite/public/config/database.php
这可能根本不存在。
对于项目内部文件引用,很多情况下直接从当前文件位置计算路径更加可靠。
includes 应该放在哪里
很多传统 PHP 网站都会有:
includes/
├── header.php
├── footer.php
├── functions.php
└── db.php
这种方式本身没有问题。
真正需要注意的是:includes 里面是什么,以及它是否应该被浏览器直接访问。
如果 db.php 中包含数据库密码,那么最好不要让它位于公开的 Web 根目录。
例如:
mywebsite/
├── config/
│ └── database.php
├── includes/
│ └── functions.php
└── public/
└── index.php
这样会比把所有内部文件全部放到 public 下更加清楚。
上传文件应该特别小心
网站允许用户上传图片、附件或者其他文件时,需要单独考虑上传目录。
例如:
storage/
└── uploads/
如果这些文件只是网站内部处理的数据,可以放在 Web 根目录之外。
如果图片必须通过浏览器直接访问,则可以把最终需要公开的图片放到:
public/uploads/
或者通过 PHP 控制访问。
最重要的是不要简单地把上传目录设置成:
777
然后允许用户上传任何文件。
777 并不是 PHP 网站上传目录的标准推荐方案。目录和文件应该根据服务器运行用户、所有者和实际读写需求设置最小必要权限。
PHP 官方的文件系统安全文档也强调,PHP 对文件系统的访问受到操作系统权限控制,应该确保程序只能够读取和修改真正需要操作的文件。
日志不要和网页文件混在一起
网站运行过程中会产生各种日志,例如:
storage/
└── logs/
├── app.log
└── error.log
日志主要用于排查问题。
例如:
PHP 程序发生错误
数据库连接失败
用户提交了异常请求
某个接口频繁返回错误
后台任务执行失败
日志通常不需要让普通访客直接通过 URL 访问。
因此,把日志目录放在 Web 根目录之外通常更加合理。
vendor 是什么
如果项目使用 Composer 安装第三方 PHP 库,通常会出现:
vendor/
例如:
vendor/
├── autoload.php
└── ...
程序可能通过:
require __DIR__ . '/../vendor/autoload.php';
加载 Composer 的自动加载器。
对于普通 PHP 网站,不需要自己手动修改 vendor 里面的第三方代码。
如果某个第三方库需要升级,通常应该通过 Composer 管理,而不是直接修改里面的文件。
database 目录不一定必须存在
有些项目会建立:
database/
├── migrations/
├── seeds/
└── backups/
用于保存数据库迁移脚本、初始化数据等。
但这不是 PHP 的强制目录。
小型网站完全可以不使用这个结构。
目录规划的目的不是让项目看起来复杂,而是让文件更容易找到,并且让不同类型的数据和代码有清楚的边界。
一个小型 PHP 网站可以很简单
如果只是一个个人网站或者小型内容网站,没有必要一开始就建立几十个目录。
例如:
mywebsite/
├── config/
│ └── database.php
├── includes/
│ ├── header.php
│ └── footer.php
├── uploads/
├── public/
│ ├── index.php
│ ├── article.php
│ ├── css/
│ └── js/
└── composer.json
这已经足够清楚。
如果网站规模继续扩大,再增加:
app/
storage/
database/
tests/
也不迟。
大型项目才需要进一步分层
当 PHP 网站发展成大型 CMS、电子商务平台或者企业系统后,可以进一步划分:
mywebsite/
├── app/
│ ├── Controllers/
│ ├── Models/
│ ├── Services/
│ ├── Repositories/
│ └── Middleware/
├── config/
├── database/
│ ├── migrations/
│ └── seeders/
├── storage/
│ ├── cache/
│ ├── logs/
│ └── uploads/
├── tests/
├── vendor/
├── public/
│ ├── index.php
│ ├── css/
│ ├── js/
│ └── images/
└── composer.json
但这并不意味着每个 PHP 网站都必须采用这套结构。
如果只有十几个 PHP 文件,却建立十几层目录,反而会增加维护难度。
目录结构应该随着项目复杂程度增长,而不是为了追求所谓的专业感而提前复杂化。
Apache、Nginx 和 PHP 项目目录不是一回事
还需要把三个概念分开:
Apache/Nginx:负责接收 HTTP 请求。
Web 根目录:决定哪些文件能够通过网站路径映射到服务器文件。
PHP 项目目录:保存整个应用程序。
例如:
/home/user/mywebsite/
├── app/
├── config/
├── storage/
├── vendor/
└── public/
└── index.php
Web 服务器可以只把:
/home/user/mywebsite/public
作为网站根目录。
Apache 使用 DocumentRoot 指定这样的目录;Nginx 则通过 root 等配置指定请求对应的文件系统路径。
这样做以后,网站的内部结构和浏览器能够访问的内容就自然分开了。
如果使用虚拟主机,路径还可能完全不同
很多开发者看到:
/var/www/html
就以为所有 Linux PHP 网站都是这样。
实际上并不是。
Apache 可以为不同虚拟主机设置不同的 DocumentRoot。
因此可能出现:
/var/www/site1/public
/var/www/site2/public
/home/user/site3/public_html
甚至在共享主机环境中,服务器目录可能完全不同。
所以开发 PHP 网站时,最可靠的方法不是死记某一个路径,而是先确认:
当前服务器的 Web 根目录到底是什么。
最后真正需要记住的只有几件事
开发 PHP 网站之前,不需要背大量服务器目录名称。
真正重要的是理解这几个关系:
整个项目
↓
PHP代码、配置、日志、缓存、第三方库
↓
只有需要给浏览器访问的内容
↓
Web根目录
↓
用户通过URL访问
一个比较稳妥的思路是:
项目根目录
├── app 业务代码
├── config 配置
├── storage 日志、缓存、上传等运行数据
├── vendor Composer依赖
└── public 浏览器真正访问的内容
对于简单网站,也可以适当简化;对于大型项目,则可以继续细分。
最重要的原则并不是一定要使用 app、config、storage 或 public 这些名字,而是让公开文件和内部文件分开,让配置、日志和用户上传数据有明确的位置,让程序代码不要和网页静态资源全部混在一起。
一旦理解了这个关系,以后无论是在 Apache、Nginx、云服务器还是共享主机上部署 PHP 网站,看到不同的目录名称都不会再感到混乱。
真正需要掌握的不是某个服务器默认使用哪个文件夹,而是:服务器从哪里提供网站文件,PHP 程序从哪里加载内部文件,以及哪些内容根本不应该直接暴露给浏览器。
开发 PHP 网站前,应该掌握哪些服务器目录和文件结构知识
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
分享 Facebook | X | WhatsApp | LinkedIn
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP