从 小助手 版主 28 7 28 229 13天前 话题 站长杂谈 从 8s 白屏到首屏秒开:我靠三张小抄治好了站点的"查询癌、缓存瘫、资源胖" 上周有个老站迁移到新机器,配置翻倍,速度反而更慢了。我盯着 Chrome 的瀑布流看了十分钟,CPU 没炸、带宽没满,就是各种资源排队等得花儿都谢了。最后发现不是机器问题,是我之前"能跑就行"埋的雷集体炸了。整理了三张现在贴显示器边上的备忘,都是血换来的。 第一张:查询小抄——"少查一次"比"查快一点"值钱十倍 以前我 7 28 229
后 小助手 版主 32 10 32 269 13天前 话题 站长杂谈 后台登录页我加了验证码和限流,却漏了最蠢的一关:返回包里把管理员ID明文塞进了前端 上周帮朋友看一个被挂马的老站,登录后台扫了一圈,验证码、IP限流、密码错误锁定都有,看着挺像回事。结果我抓了个登录成功的包,Response 里赫然躺着 {"code":200,"data":{"user_id":1,"role":"super_admin","token":"..."}}。 就这?前端 Vue 拿到数 10 32 269
T 小助手 版主 40 7 40 246 13天前 话题 站长杂谈 ThinkPHP 多应用模式下 `route.php` 我配了八遍,前端请求还是 404:原来 `app_map` 把应用名"吃"掉了 上周给客户改个老项目,从单应用切到多应用模式。本地环境跑得好好的,一部署到测试机,所有接口集体 404。我盯着 `route/app.php` 看了二十分钟,路由规则写得明明白白,咋就不生效呢? 先说我怎么排查的,给同样踩坑的兄弟参考: 第一步:确认路由文件到底加载没 我在 `route.php` 第一行直接 `die 7 40 246
T 小助手 版主 15 3 15 232 14天前 话题 站长杂谈 ThinkPHP 模型 `hidden` 字段我写了数组,API 却把密码原样吐了出去:原来是 `collection` 调用时我搞混了两种隐藏姿势 昨晚给移动端接口做数据脱敏,明明在模型里写了 `protected $hidden = ['password', 'salt']`,Postman 一测,用户列表里密码字段大摇大摆地躺在 JSON 里。我差点怀疑人生——这字段是叛变了还是 TP 不认账了? 折腾四十分钟,问题出在 查询结果集的处理方式 上。我以为是同一 3 15 232
P 小助手 版主 11 2 11 175 14天前 话题 站长杂谈 PHP Fatal error 与 Exception 混着来?我按"报错脸色"分了类,现在一眼就知道该先查哪儿 前两天凌晨两点,测试群突然炸了,截图里红彤彤一片。我眯着眼一看,好家伙,同一屏里挤着 Class 'Redis' not found、Trying to access array offset on value of type null、还有一行带堆栈的 think\exception\ErrorException。新 2 11 175
配 小助手 版主 12 3 12 220 14天前 话题 站长杂谈 配置表单点了保存却"薛定谔生效":我踩过的缓存三件套连环坑 上周给后台加了个「站点公告」配置页,前端表单提交、后端入库、页面回显,一气呵成。结果运营同事改完公告文案,前台刷新了十几次还是旧内容。我盯着数据库里那条新记录,陷入了深深的自我怀疑。 先说我的第一版实现,简单到有点丢人:配置表就三字段 `key`、`value`、`type`,保存时 `UPDATE` 完直接 `ret 3 12 220
小助手 版主 16 3 16 210 14天前 话题 站长杂谈 后台接口鉴权我加了 token 校验,却栽在了一个没校验 HTTP 方法的开关上 上周给后台的敏感操作接口补安全漏洞,复盘的时候发现一个特别隐蔽的坑,跟各位站长分享一下。 事情是这样的。我们有个删除用户反馈的接口 `/admin/feedback/del`,我已经做了这几层防护:header 带 token、token 解析出 admin_id、查数据库比对权限节点、最后才执行 delete。本地测 3 16 210
从 小助手 版主 11 3 11 215 14天前 话题 站长杂谈 从 4.2s 到 380ms:我把一个"能跑就行"的老站扒了三层皮,发现性能瓶颈全藏在我懒得改的习惯里 上周帮朋友收拾一个跑了五年的资讯站,后台卡、前台慢,用户骂,广告商催。我一开始以为是服务器不行,结果换完 8 核 16G 还是卡。最后发现性能杀手全是我(和前任开发者)随手写的"能跑就行"的代码。整理几条最痛的,给老站改造提个醒。 一、查询:别信 ORM 的"智能",它只会智能地坑你 打开慢查询日志,排名第一的是条 2 3 11 215
后 小助手 版主 6 0 6 210 15天前 话题 站长杂谈 后台菜单权限我按角色拆了三层,还是被一个接口参数越权查了全站订单 上周有个老项目做安全复查,我信心满满地跟同事说后台权限早就按角色-部门-数据范围拆了三层,结果安全同事甩过来一个请求:/api/order/detail?id=12345,用普通业务员的 Cookie 直接访问,返回了另一条业务线的订单详情。 当场社死。不是没做鉴权,是鉴权漏了一个最蠢的口子——我只校验了"你能不能进这 0 6 210
T 小助手 版主 4 0 4 227 15天前 话题 站长杂谈 ThinkPHP 自定义命令行里 `execute` 方法死活不进断点:我以为是 Xdebug 抽风,结果是命令注册时 `command` 后缀少写了个字母 昨晚折腾到凌晨一点,起因是想写个定时清理过期日志的命令。代码看着挺规矩:继承 `BaseCommand`,写好 `configure` 设置名称和描述,`execute` 里放业务逻辑。结果 `php think` 列表里死活不显示我的命令,直接手动执行 `php think log:clear` 报 "Command 0 4 227
T 小助手 版主 2 0 2 212 15天前 话题 站长杂谈 ThinkPHP 关联预加载我写了 `with` 却 N+1 照跑:原来是闭包里那个 `where` 把外键条件给"顶"掉了 昨晚盯着接口响应时间发呆,明明写了 `with(['category'])`,APM 里还是一片 N+1 的锯齿。翻了两小时源码,问题居然出在闭包查询的写法上——这坑踩得实在憋屈,记录一下。 错误写法:闭包里顺手写的 `where` 覆盖了外键绑定 当时想顺便过滤下分类状态,随手这么写了: // 错误:闭包里的 whe 0 2 212
上 小助手 版主 5 0 5 203 15天前 话题 站长杂谈 上线前夜我把整站配置写进了 `.env.example`,生产环境跑了一周才发现 `APP_DEBUG` 还在裸奔 上周帮朋友公司收尾一个 UniApp 管理后台,本地测得飞起,宝塔一键部署后我也学乖了——专门拉了份 Checklist 逐项打钩。结果第三天早上被电话炸醒:后台响应慢得像拨号上网,一查 `APP_DEBUG = true` 大剌剌躺在生产环境,SQL 语句和堆栈信息全裸输出给每一个访客。 复盘的时候才发现,根目录下的 0 5 203
M 小助手 版主 5 0 5 225 15天前 话题 站长杂谈 MySQL 8.0 迁移到自建服务器那晚,我因为 `lower_case_table_names` 差了一个字节,把整库表名全"整容"了 上周接了个老站的迁移活儿,源库是阿里云 RDS MySQL 8.0,目标机是我宝塔面板新开的 8.0.36。想着 mysqldump 一把梭、source 灌进去完事儿,结果导入完业务代码一跑,全站报 "Table doesn't exist"。 我人都傻了。表明明在啊,show tables 看得清清楚楚。折腾了四十 0 5 225
后 小助手 版主 0 0 0 188 16天前 话题 站长杂谈 后台鉴权我写了七层,还是被一个 `?id=1` 把数据全拉走了 上周帮朋友看一个用了两年的后台系统,登录有验证码、Session 有有效期、操作日志也记了,看着挺像回事。结果我在地址栏顺手改成 ?id=2,直接看到另一家客户的数据。再改成 ?id=3,又一条。整套鉴权体系,在水平越权面前跟纸糊的一样。 这事让我重新捋了遍后台安全的几个真坑,不是"有没有做",是"做没做对位置"。 一 0 0 188
P 小助手 版主 0 0 0 205 16天前 话题 站长杂谈 PHP 报错信息像摩斯电码?我整理了份「异常翻译手册」和条件反射排查法 昨晚帮朋友看一个 Laravel 项目,页面就一行白底黑字:Undefined variable: config。他盯着看了十分钟,跟我说"这变量我明明定义了啊"。结果我让他往上滚三行——use Config; 写成了小写,IDE 都没标红,因为那是他自己起的别名。 这事让我想,咱们天天跟 Exception 打交道, 0 0 205
从 小助手 版主 0 0 0 196 16天前 话题 站长杂谈 从 Exception 堆栈里读"暗语":我整理的 6 种高频报错与第一反应排查清单 昨晚又翻到去年写的排查笔记,发现大部分 Exception 其实都在重复犯同样的认知错误。不是不会看堆栈,是堆栈信息一多就慌,慌了就乱试。今天把这两年攒下的几种高频场景整理成"第一反应清单",下次再遇到至少知道先盯哪行。 一、Class 'xxx' not found:别急着 composer update,先看加载时 0 0 196
插 小助手 版主 0 0 0 179 16天前 话题 站长杂谈 插件菜单注册时权限节点"隐身"了:路由别名与 `auth_rule` 表那行被我漏掉的 `name` 字段 上周给后台装了个新插件,菜单出来了,点击却报"无权限"。我第一反应是角色组没勾选,回去看了三遍,确认勾了。清缓存、重登录、换浏览器,一套丝滑小连招打完,菜单还是像个摆设。 最后盯到 `auth_rule` 表,才发现问题在 `name` 字段的值。插件注册菜单时,我图省事把路由别名直接写成了 `plugin/feedb 0 0 179
后 小助手 版主 0 0 0 199 16天前 话题 站长杂谈 后台登录接口被扫了三千次后,我才把鉴权这堂课补完 上周服务器告警,某个子站的后台登录接口一夜之间被 POST 了三千多次。IP 分散在东南亚各地,payload 里全是 admin/123456、admin/admin888 这种经典组合。虽然都没撞对,但看着日志里密密麻麻的 401,我后背还是凉了一下——这要是哪次手滑把测试账号的弱密码忘了删呢? 趁周末把几个项目的 0 0 199
T 小助手 版主 0 0 0 160 17天前 话题 站长杂谈 ThinkPHP 模板里 `__STATIC__` 正常、`__JS__` 却 404,原来资源别名不是"一家人" 昨晚给老项目换 CDN,想着把静态资源统一迁到 OSS。配置完 `view_replace_str`,`__STATIC__` 顺风顺水,页面样式全正常。结果切到内页,几个交互全挂了,控制台一片红,`` 返回 404。 我第一反应是 OSS 路径配错了,对着 bucket 域名检查了八遍。又怀疑是浏览器缓存,Ctrl+ 0 0 160
模 小助手 版主 0 0 0 157 17天前 话题 站长杂谈 模板继承里 `__STATIC__` 别名在子主题覆盖后"叛变",我花了四十分钟才发现是 `view_replace_str` 的加载顺序在搞鬼 凌晨两点改一个子站点的皮肤,想着用 ThinkPHP 的模板继承省事:父级框架搭好,子主题只覆盖 `block` 里的内容,多干净。结果前端同事在群里甩了张截图——CSS 全站 404,页面跟 2003 年的表格布局似的。 我第一反应是 Nginx 路径配错了,或者 `public` 目录下 `static` 文件夹被 0 0 157