真正有效的隔离方式是每个站点用独立数据库+独立用户+最小权限授权;共用实例时仅靠表前缀无法实现安全隔离,因MySQL权限系统不识别前缀,需通过库级隔离与精准host匹配授权来保障安全。

共用一个 MySQL 实例时,数据库名不能只靠“前缀”区分
很多人误以为在同一个 MySQL 里建 site_a_users、site_b_users 就算“隔离”,其实这只是命名习惯,不构成任何安全边界。MySQL 的权限系统不识别表名前缀,只要用户有 SELECT 权限到整个库,就能查所有表。
真正有效的隔离方式是:每个站点用独立数据库 + 独立用户 + 最小权限授权。比如:
- 建库
app_shop和app_blog(而非shared_db下一堆带前缀的表) - 创建用户
shop_user@localhost,只授SELECT, INSERT, UPDATE给app_shop.* - 创建用户
blog_user@localhost,只授SELECT, INSERT给app_blog.*
这样即使两个应用代码写错,也跨不了库。别图省事全扔一个库——后期权限回收、备份粒度、迁移拆分都会变麻烦。
XAMPP 中多个 Apache 实例连同一 mysqld,必须统一 PHP 的 MySQL 连接参数
如果你开了两个 XAMPP(比如 D:\xampp-a 和 D:\xampp-b),想让它们都连同一个 MySQL(只启动其中一个的 mysqld),关键不是改端口,而是确保两套 PHP 都指向真实运行的那个实例。
检查并统一以下三项(路径如 D:\xampp-a\php\php.ini 和 D:\xampp-b\php\php.ini):
-
mysqli.default_host = 127.0.0.1(别写localhost,Windows 下会走命名管道,容易失败) -
mysqli.default_port = 3306(必须和宿主 mysqld 实际监听端口一致) -
mysqli.default_user和mysqli.default_pw填对应站点的数据库用户名/密码,不是 root
改完重启各自 Apache,别忘了关掉非宿主 XAMPP 的 MySQL 服务(控制面板里取消勾选 “Svc”,且不点 Start)。
权限分配时,GRANT 语句的 host 匹配比想象中更严格
执行 GRANT SELECT ON app_shop.* TO 'shop_user'@'localhost' 后,PHP 用 127.0.0.1 连不上,因为 'shop_user'@'localhost' 和 'shop_user'@'127.0.0.1' 是 MySQL 里两个完全不同的账号。
常见错误场景:
- Discuz 安装页填
127.0.0.1但权限只给了root@localhost→ 连接拒绝 - 本地开发用 Docker 或 WSL,PHP 进程 IP 是
172.x.x.x,但权限只开给%或localhost→ 连不上
解决办法很直接:
- 明确知道连接来源 IP,就用具体地址授权:
GRANT ... TO 'shop_user'@'127.0.0.1' - 不确定来源(比如多环境切换),用
'shop_user'@'%',但必须配合防火墙限制 3306 入口仅限内网 - 永远不要删掉
root@localhost—— phpMyAdmin 依赖它,删了就打不开管理界面
字符集与认证插件不匹配,会导致“连接成功但查询失败”
XAMPP 8.0+ 默认启用 caching_sha2_password 认证,而老项目(如 Discuz X3.4、旧版 Laravel)的 PDO/mysqli 扩展可能不支持,现象是:连接不报错,但执行 SELECT 时卡住或返回空结果。
快速验证方式:用命令行连一下
mysql -u shop_user -p -h 127.0.0.1 app_shop
如果提示 Authentication plugin 'caching_sha2_password' cannot be loaded,就得切回兼容模式:
- 进 phpMyAdmin,执行:
ALTER USER 'shop_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_real_password'; - 或者命令行:
mysql -u root -p -e "ALTER USER 'shop_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx'; FLUSH PRIVILEGES;"
注意:改完要 FLUSH PRIVILEGES,且该用户后续必须用新密码连接 —— 旧密码会失效。
权限配置不是一次性动作,每次新增站点、更换开发环境、升级 XAMPP 版本,都要重新核对 host 匹配、认证方式、字符集三者是否咬合。最容易被忽略的是:你以为改了 my.ini 就生效,其实没重启 mysqld;你以为 GRANT 了就 OK,其实漏了 FLUSH PRIVILEGES;你以为用 localhost 没问题,结果 PHP 走了 TCP 而不是 socket。


















