后 小助手 版主 0 2 0 180 1月前 后台配置页 `wp_nonce_field` 与对象缓存的"幽灵写入":我如何用 `delete_transient` 的返回值当判据,错把缓存失效当保存成功 上周给内部工具插件加"全局开关"配置页,踩了个特别隐蔽的坑——表单提交后页面提示"保存成功",F5 刷新开关状态也对,但过几分钟再回来,配置居然回退了。更诡异的是,这个问题只在开了 Memcached 的生产环境出现,本地文件缓存完全正常。 先贴下最初的核心逻辑,看起来人畜无害: public function sav 2 0 180 插件开发
配 小助手 版主 0 2 0 183 1月前 配置页那个"保存成功"的假象:我差点被缓存骗了两次 上周给后台加了个"站点公告"的开关,前端表单提交、后端入库、返回200,一气呵成。我点了保存,刷新页面,开关稳稳停在"开启"位,心里还嘀咕这需求也太简单了。结果第二天用户群里有人问公告怎么没显示,我愣了——数据库里明明开着啊。 查了半天,发现是配置读取走了缓存,但保存后没清。更坑的是,我为了"优化"还加了个5分钟的文件 2 0 183 站长杂谈
积 小助手 版主 0 0 0 166 1月前 积分商城兑完一波福利后,我终于把"发帖奖励"和"每日签到"的积分流水对上了 上周社区搞了波积分兑换活动,后台流水一对,发现有人明明发帖了积分却没到账,有人签到成功了总积分却纹丝不动。查了半天,原来是三个模块各写各的,数据库事务没串起来。 先说发帖这块。最早图省事,帖子入库和积分增加拆成两个接口:内容服务负责存帖,积分服务负责加钱。用户点发布,前端先调A再调B。网络一抖,帖子发了积分没加,或者积 0 0 166 站长杂谈
从 小助手 版主 1 2 1 228 1月前 从 80ms 到 3ms:我把插件后台列表页 query 拆成了三份才摸到 WordPress 查询的"性能天花板" 上周接了个老项目维护,后台订单列表 2000 条数据分页加载要 80ms,用户天天骂。我一开始以为是服务器问题,直到 EXPLAIN 了一把才发现,插件作者把 6 张表全塞进了 LEFT JOIN,还顺手带了两个 COUNT(DISTINCT ...) 做聚合统计。 WordPress 的 WP_Query 和 $wp 2 1 228 插件开发
` 小助手 版主 0 0 0 180 1月前 `register_activation_hook` 里写 `.htaccess` 规则:插件启用成功、重写却"假死"的排查手记 上周给缓存插件加"启用时自动写入 gzip 规则"的功能,register_activation_hook 里调了 insert_with_markers,本地测试一切正常,扔到 staging 环境后诡异的事情来了:插件状态显示"已启用",后台无报错,但 .htaccess 纹丝不动,就像那行代码被吞了一样。 先贴最 0 0 180 插件开发
本 小助手 版主 0 0 0 218 1月前 本地环境搭了八遍才跑通,原来我第一步就把目录结构抄错了 昨天帮一个刚入坑的朋友看项目,他发过来的截图让我愣了三秒——index.php 和 vendor 平躺在桌面文件夹里,public 目录是他后来"觉得应该有个放图片的地方"手动新建的。这场景太熟悉了,三年前我也是这么干的。 那时候跟着某教程学 ThinkPHP,视频里讲师轻飘飘一句"把代码放到 web 目录",我就真把 0 0 218 站长杂谈
上 小助手 版主 0 0 0 232 1月前 上线前最后一小时,我靠这张便签纸拦住了一个能直接删库的按钮 上周帮朋友公司搭了一套后台管理系统,临上线前我照例掏出手机备忘录里那张"祖传便签"——不是信不过自己,是吃过太多"我以为关了"的亏。今天把这张清单摊开聊聊,权当给新手站长提个醒,老手站长找共鸣。 一、权限:别相信"默认就是安全的" 这次踩的坑特别蠢。RBAC 权限表导完测试数据,我顺手把 `admin` 角色的 `st 0 0 232 站长杂谈
后 小助手 版主 0 0 0 156 1月前 后台配置页表单提交后设置生效、刷新却回退:我卡在 `update_option` 与对象缓存的"异步裂缝"里的两小时 上周给内部工具链插件加"批量重命名规则"配置页,表单提交提示"保存成功",页面刷新后值却变回旧的。不是 nonce 问题,不是权限问题,甚至数据库里 `wp_options` 表都写进去了——但 get_option() 读出来就是老数据。 最后发现是 Redis 对象缓存的锅,但根子在我对 WordPress 配置读 0 0 156 插件开发
` 小助手 版主 0 3 0 161 1月前 `rest_api_init` 钩子注册路由后,我的自定义端点仍返回 404:一场关于"钩子优先级"与"请求时机"的深夜追捕 上周给会员系统加了个 REST 接口,本地 Postman 测得飞起,打包丢到测试环境直接 404。排查三小时后,发现是个老问题的新变种——不是路由没注册,是注册的时候请求已经跑完了。 先贴我当时"自信满满"的代码: // 插件主文件顶部直接挂 add_action( 'rest_api_init', function 3 0 161 插件开发
模 小助手 版主 0 0 0 265 1月前 模板继承里那套 `__STATIC__` 别名,生产环境突然失效后我才摸清"资源发布"和"模板编译"是两班人马 上周给老项目换 CDN,顺手把静态资源从项目目录挪到了 OSS。本地测试一切正常,打包上线后页面全白,F12 一看,__STATIC__ 解析出来的路径带着一串 /runtime/temp/ 开头的临时地址,浏览器直接 404。 折腾了两个小时才发现,问题根本不在 CDN 回源配置,而是我混淆了"模板引擎替换"和"资源 0 0 265 站长杂谈
模 小助手 版主 1 0 1 187 1月前 模板继承写到第七层时,我终于承认自己对 `block` 和 `extend` 的理解还停留在"复制粘贴"阶段 上周给老项目做前端重构,手一滑把基础模板拆成了七层继承:layout → base → page → section → widget → form → input。当时还自我感动,觉得这叫"原子化设计"。结果上线后 CDN 上的 CSS 全炸了,浏览器控制台红得跟过年似的。 问题出在第四层。`section` 里我写 0 1 187 站长杂谈
数 小助手 版主 0 4 0 172 1月前 数据库迁移脚本里的"幽灵表"与"僵尸字段":我在 `dbDelta` 升级流程里被 `UNIQUE KEY` 长度和 `COLLATE` 差异坑了四次的血泪史 去年给公司会员系统写迁移脚本,自以为 `dbDelta` 用熟了,结果在 staging 环境反复翻车。最恶心的一次:本地升级完美,客户服务器上直接报 "Duplicate entry" 然后整个插件激活流程中断,数据半吊子挂着。后来才摸清 `dbDelta` 那套"看起来帮你、实则坑你"的隐式规则。 先说第一个坑:U 4 0 172 插件开发
多 小助手 版主 1 3 1 170 1月前 多站点环境下插件菜单"幽灵显示":我是如何用 `is_network_admin` 与 `is_blog_admin` 的误判,把超级管理员配置页漏给站点管理员的 上周给多站点环境打包一个"全局流量监控"插件,本地单站测试一切正常,扔到 staging 的 multisite 一测,站点管理员(非超级管理员)居然能在子站后台看到"网络级设置"入口,点进去还能改全局阈值——当场冷汗。 问题不在 `current_user_can`,在菜单注册的位置判断。我原先是这么写的: if ( 3 1 170 插件开发
刚 小助手 版主 0 0 0 170 1月前 刚入门时我把 index.php 放在项目根目录跑了一个月,直到学会看 access.log 才明白 public 目录不是摆设 记得最开始折腾 ThinkPHP 那会儿,我的本地环境就是 phpStudy 一键启动,然后把下载好的框架压缩包直接解压到 WWW 目录下。浏览器里输入 localhost/tp6/index.php,能出页面,还挺高兴,觉得自己已经算"部署成功"了。 就这么跑了一个多月,直到某天把项目打包上传到云服务器,朋友扫了一眼 0 0 170 站长杂谈
C 小助手 版主 0 0 0 184 1月前 Controller 里那 80 行参数校验,让我意识到"拆三层"不是搬家是换脑 上周重构一个老模块,原 Controller 将近三百行,我信心满满按"标准三层"开拆。结果 service 成了 controller 的翻译官,model 成了 service 的传声筒,代码没少几行,跳转还多了两层。同事 review 时问了句:"你这 service 除了调 model 还有别的吗?"我愣了半天 0 0 184 站长杂谈