本地环境跑起来那天,我才搞懂 `public/index.php` 到底在守护什么
刚开始折腾 ThinkPHP 那会儿,我把项目 zip 往宝塔文件管理器一丢,域名指过去,结果 500。翻日志看到 "Unable to load the requested class",愣是以为框架坏了,差点去官网下第二遍。后来才反应过来,我直接访问的是 `application/controller/Index.php`,连入口文件长啥样都没正眼瞧过。
现在回头看,目录结构那层窗户纸捅破就一句话:web 服务器只能认识 `public` 那个门,里头的东西你再熟,不走正门全是白搭。我当时的憨批操作是把整个项目根目录设成运行目录,`.env` 和 `vendor` 直接暴露在外,搜索引擎一抓一个准。后来学乖了,Nginx 的 `root` 只写到 `/public`,`location /` 里 `try_files` 兜住 `index.php`,这才算把门关上。
入口文件那几行代码我打印出来贴显示器边上了。`require __DIR__ . '/../vendor/autoload.php'` 是喊 Composer 起床,`$http = (new App())->http` 是框架启动,`$response->send()` 之前全是你写的业务逻辑。有回我本地改完代码刷新没反应,清浏览器缓存、重启电脑全试了,最后发现改的是线上 FTP 里的文件,本地 PHP Study 跑的是另一个副本。从此我桌面必开两个 CMD 窗口,一个 `php -v` 看环境,一个 `php think run` 起内置服务器,端口 8000 成了肌肉记忆。
本地调试环境我踩过最阴的坑是 PHP 版本。项目要求 7.4,我小皮面板默认 7.2,`??=` 这种运算符直接报语法错误,定位还偏到最后一行,害我怀疑人生半小时。现在装环境先锁版本,再开 `display_errors = On`,`error_log` 指到固定路径,线上绝对不敢这么干。Xdebug 我也装了,但说实话,新手期 `dump()` 和 `die()` 才是亲兄弟,断点反而让我懵圈。
还有个小习惯分享:我在项目根目录建了个 `_local` 文件夹,放数据库备份、测试图片、乱七八糟的草稿,`.gitignore` 里第一时间把它塞进去。这文件夹不上线、不进版本,专供本地折腾,和 `runtime` 一个待遇。有回没忽略,把带测试账号的 SQL 推到了码云,虽然私有仓库,后背还是凉了一阵。
现在每次开新项目,我先不做功能,就盯着目录结构看五分钟:入口守没守好、敏感文件藏没藏好、本地和线上的差异怎么隔离。这五分钟省下的返工时间,够我写三个接口了。