MySQL用户无CREATE权限执行CREATE TABLE时会报错“1142 CREATE command denied”,需用root登录并执行GRANT CREATE ON myapp_db.* TO ‘webapp’@’localhost’; FLUSH PRIVILEGES; 授权必须精确匹配数据库名与主机名。

MySQL 用户没有 CREATE 权限时会报什么错
执行 CREATE TABLE 时直接失败,典型错误是:
SQLSTATE[42000]: Syntax error or access violation: 1142 CREATE command denied to user 'webapp'@'localhost' for table 'users'
。这不是语法错误,而是权限拒绝——MySQL 在解析阶段就拦截了,连表结构校验都不会做。
给 PHP 使用的数据库用户授 CREATE 权限的正确方式
必须用高权限账号(如 root)登录 MySQL,然后对目标数据库显式授权,不能只给 ALL PRIVILEGES 却漏掉 ON database_name.* 的范围限定:
GRANT CREATE ON `myapp_db`.* TO 'webapp'@'localhost'; FLUSH PRIVILEGES;
-
CREATE权限必须绑定到具体数据库(myapp_db),授予.*才生效;给*.*是全局权限,不推荐 - 如果 PHP 连接时指定了
database参数(如 PDO DSN 中含dbname=myapp_db),那授权也必须对应这个库名,否则仍被拒 - 避免用
GRANT ALL ON myapp_db.*—— 会意外包含DROP、ALTER等高危权限
PHP 代码里检测建表权限是否生效
别等 CREATE TABLE 报错才处理,提前查 information_schema.SCHEMA_PRIVILEGES 更稳妥:
$pdo = new PDO('mysql:host=localhost;dbname=myapp_db', $user, $pass);
$stmt = $pdo->query("SELECT COUNT(*) FROM information_schema.SCHEMA_PRIVILEGES WHERE GRANTEE = /"'$user'@'localhost'/" AND TABLE_SCHEMA = 'myapp_db' AND PRIVILEGE_TYPE = 'CREATE'");
$hasCreate = (int)$stmt->fetchColumn() > 0;
注意:GRANTEE 值要和实际用户定义完全一致(包括引号、主机名),大小写敏感;生产环境建议缓存该结果,避免每次请求都查元数据表。
立即学习“PHP免费学习笔记(深入)”;
为什么在 Docker 或云数据库里授权后还是没用
常见脱节点:
- Docker 中 MySQL 容器重启后,手动执行的
GRANT没有持久化——得把授权语句写进初始化 SQL 文件(如/docker-entrypoint-initdb.d/01-grant.sql) -
阿里云 RDS、腾讯云 CDB 等托管服务禁止直接操作
mysql.user表,必须走控制台「账号管理 → 授权」界面,且只支持库级授权,不支持表级或列级 - PHP 连接用的是
127.0.0.1而不是localhost,导致授权时写的'webapp'@'localhost'不匹配,应统一用'webapp'@'%'或明确指定 IP 段
权限问题本质是 MySQL 的访问控制链路(用户+主机+数据库+操作)全匹配才放行,少一个环节就卡住,不能只盯着 PHP 代码改。
