本地环境搭了八遍才跑通,原来我第一步就把目录结构抄错了

站长杂谈 18 浏览 0 回复 返回上级

昨天帮一个刚入坑的朋友看项目,他发过来的截图让我愣了三秒——index.phpvendor 平躺在桌面文件夹里,public 目录是他后来"觉得应该有个放图片的地方"手动新建的。这场景太熟悉了,三年前我也是这么干的。

那时候跟着某教程学 ThinkPHP,视频里讲师轻飘飘一句"把代码放到 web 目录",我就真把整个项目包丢进了 Nginx 的 root。能跑吗?能跑。安全吗?直到我在日志里看到有人直接访问 /application/database.php 才后知后觉。

目录结构不是"约定俗成",是"物理隔离"

现在每次开新项目,我会先画个草图给自己看:

project/
├── app/              ← 应用逻辑,对外不可见
├── config/           ← 配置文件,对外不可见  
├── extend/           ← 扩展类库,对外不可见
├── public/           ← ← ← 唯一对外开口
│   ├── index.php     ← 入口文件,仅此一个
│   ├── static/       ← 编译后的 CSS/JS
│   └── uploads/      ← 用户上传(注意权限)
├── runtime/          ← 缓存日志,对外不可见
└── vendor/           ← 依赖包,对外不可见

关键点就一条:web 服务器只认 public,其他目录对它来说不存在。 不是"建议",是"必须"。Nginx 配置里那个 root /var/www/project; 改成 root /var/www/project/public; 的瞬间,才算真正入门。

入口文件那几行,我抄了半年没看懂

TP6 的 public/index.php 默认长这样:

<?php
require __DIR__ . '/../vendor/autoload.php';
$http = (new \think\App())->http;
$response = $http->run();
$response->send();
$http->end();

有段时间我嫌它"不够简洁",自己改成了:

<?php
require '../vendor/autoload.php';
(new \think\App())->run();

本地能跑,上线就 500。查了半天才发现,__DIR__ 和相对路径在 CLI 模式和 FPM 模式下解析结果可能不同,而 $http->end() 负责清理连接池和日志写入,少了它高并发下会漏日志。现在我再也没动过官方模板,看不懂的先留着,比"优化"后埋雷强。

本地环境我现在的偷懒三件套

早期我坚持用"原生"环境:本机装 Nginx、PHP、MySQL,版本自己配,扩展自己编,一个下午能搭好算快的。现在?

Windows: Laragon,绿色版,PHP 版本下拉切换,自带 Mail Catcher 和 Redis,数据库文件直接躺在项目旁边,重装系统拷走文件夹就行。

Mac: Herd 或者继续 Laragon 的 WSL2 方案。Herd 的坑是默认 PHP 版本偏新,老项目得手动指定,但 herd link 秒配本地域名确实香。

统一习惯: 每个项目配一个 .env.local,数据库名带 _dev 后缀,上传目录软链到 storage/app/public,绝不直接往 public/uploads 写东西——防止某天手滑把本地测试图同步到生产环境。

一个让我红温的调试细节

TP6 默认开启 app_debug 时,报错页面会暴露绝对路径。本地无所谓,但有一次我截图发群求助,朋友秒回:"你用户名是 realname 啊?"

现在我的 .env.local 里固定加两行:

APP_DEBUG = true
APP_TRACE = false

调页面用 debug,但关闭右侧那个详细的请求追踪面板——它会把 SQL 参数、Session ID 全摊开来。本地也不是法外之地,养成肌肉记忆,上线才不会忘。

你们本地环境现在还折腾吗?我观察到一个现象:老站长越来越懒,新站长越来越爱"从零编译"。可能踩过坑才知道,能跑起来的环境才是好环境,至于它底层是 Docker、WSL 还是远古的 phpStudy,真没那么重要。

评论0
回复 · 0
还没有回复
微信客服 微信客服