Xiuno BBS 轻、快,但二开资料少,很多坑只能自己踩。我们给欣文校园做插件(App 下载页、单页站、App 接口层)的过程中,攒下这 6 条,按「坑度」从高到低排。
1. 改了没生效?先删编译缓存
Xiuno 的 _include() 会把插件文件编译缓存到 tmp/plugin_<id>_*,且没有 mtime 检查——改完 php/htm 不删缓存,改动永远不生效。九成「我明明改了」的问题都是它。要么手动删,要么部署脚本里固定加一步 rm tmp/plugin_<id>_*。
2. 伪静态规则:目标最后一段必须是路由名
nginx 里写 rewrite ^/x$ /index.php last; 是对的;写成带 query 形式(/index.php?r=xxx)就是错的。记住一条:rewrite 的目标最后一段必须是路由名。
3. FPM 禁了 exec 系函数
生产环境 PHP-FPM 通常封掉 exec / shell_exec / system。我们最初想在服务端用命令行工具画二维码,直接哑火——最后改成浏览器端用 jquery.qrcode 画,反而更快。
4. .user.ini 被 chattr 锁定
想改 .user.ini,先 chattr -i,改完记得 chattr +i 加回去。跳过这一步,要么改不动,要么改完忘了锁。
5. 卸载钩子的文件名是 unstall.php
不是 uninstall——官方就是这么拼的(少一个 l)。按「正确拼写」命名,卸载钩子永远不会执行。
6. 最隐蔽:utf8 三字节截断
当数据库 sql_mode 为空、表是 utf8(三字节)时,正文里出现 4 字节的 emoji,UPDATE 会静默截断该字段之后的所有内容——不报错、不告警,就是内容悄悄丢了。我们的处理:把涉及的表转 utf8mb4(站点 conf.php 的 charset 同步改),并把这条写进新插件的安装检查。如果站点出现过「内容莫名缺一截」,先怀疑它。
另外两条 CLI 相关的小经验:命令行造用户直接走 db_* 函数直插直删(model 钩子在 CLI 下不可用);CLI 跑完记得把站点新建的 root 属主日志文件 chown 回 www。