17370845950

php创建数据库怎么备份初始_php建库后备份空库法【技巧】
空库备份需用 mysqldump --no-data --databases --default-character-set=utf8mb4 显式导出建库语句和空表结构,避免漏库、乱码及权限缺失;PHP 中须用 escapeshellarg() 防注入,并单独处理 GRANT 权限。

PHP 创建数据库后立刻备份空库,为什么不能直接 mysqldump?

因为 mysqldump 默认只导出「有数据的表」,如果刚建库、还没建表或表为空,执行 mysqldump -d(仅结构)又不带 --no-create-db 时,可能漏掉 CREATE DATABASE 语句;而带 --create-options 又可能混入引擎/字符集冗余参数,导致还原失败。空库备份的关键不是“有没有数据”,而是“结构定义是否可完整重建库+权限上下文”。

用 PHP 调用 mysqldump 备份空库的 3 个必要参数

必须显式控制三件事:强制输出建库语句、确保导出空表结构、避免依赖当前连接的默认库上下文。推荐组合如下:

  • mysqldump --no-data --skip-triggers --skip-routines --skip-events --databases :强制包含 CREATE DATABASE IF NOT EXISTSUSE,且不导任何数据或逻辑对象
  • 务必指定 --databases(复数形式),否则 mysqldump db1 不会输出 CREATE DATABASE,还原时需手动建库
  • 加上 --default-character-set=utf8mb4,避免服务端默认字符集与客户端不一致导致注释或库名乱码

PHP 中安全调用 mysqldump 的写法(非 exec 简单拼接)

直接拼接 $dbname 到命令行有 SQL 注入风险(库名含破折号、空格、特殊字符时失败甚至被利用)。正确做法是用 escapeshellarg() 包裹,并检查返回值:

  
$dumpCmd = sprintf(
    'mysqldump --no-data --skip-triggers --skip-routines --skip-events --databases %s --default-character-set=utf8mb4 -u %s -p%s %s > %s',
    escapeshellarg($dbname),
    escapeshellarg($user),
    escapeshellarg($pass),
    escapeshellarg($dbname),
    escapeshellarg($backupPath)
);
$result = shell_exec($dumpCmd . ' 2>&1');
if (strpos($result, 'ERROR') !== false || !file_exists($backupPath)) {
    throw new RuntimeException('mysqldump failed: ' . $result);
}

注意:

-p 后直接跟密码虽方便,但会暴露在进程列表里;生产环境建议改用配置文件(--defaults-extra-file=/path/to/my.cnf)。

空库备份后还原时最容易忽略的权限问题

备份文件里只有 CREATE DATABASECREATE TABLE,不含 GRANT。如果原库绑定了特定用户(如 'app'@'localhost'),还原后该用户无法访问——因为 mysqldump 默认不导权限。需要额外用 mysql -e "SHOW GRANTS FOR 'app'@'localhost';" 单独导出并还原,或在建库后手动执行 GRANT ... ON `mydb`.* TO ...。这点在自动化部署脚本中常被跳过,结果应用连不上空库。