本文目录导读:

在PHP项目中配置数据库备份计划,通常不是由PHP代码自身作为调度中心(持续运行的后台进程),而是结合操作系统的计划任务(如Linux的Cron或Windows的任务计划程序)来定时执行一个PHP(或Shell/Batch)脚本。
以下是几种常见的配置方法,从手动脚本到自动化工具,按推荐程度排序:
核心逻辑:创建一个备份脚本
这个脚本(backup_db.php)负责执行数据库备份命令,并将结果保存到指定目录。
步骤 1:编写备份脚本 (backup_db.php)
<?php
// 数据库配置
$DB_HOST = 'localhost';
$DB_USER = 'your_db_user';
$DB_PASS = 'your_db_password';
$DB_NAME = 'your_database_name';
// 备份文件配置
$BACKUP_DIR = '/path/to/your/backups'; // Linux路径,确保PHP有写入权限
$DATE = date('Y-m-d_H-i-s');
$BACKUP_FILE = $BACKUP_DIR . '/' . $DB_NAME . '_' . $DATE . '.sql';
// 1. 检查备份目录是否存在,不存在则创建
if (!is_dir($BACKUP_DIR)) {
mkdir($BACKUP_DIR, 0755, true);
}
// 2. 执行 mysqldump 命令 (以MySQL为例)
$command = "mysqldump --opt -h {$DB_HOST} -u {$DB_USER} -p{$DB_PASS} {$DB_NAME} > {$BACKUP_FILE} 2>&1";
// 执行命令并获取输出和返回码
exec($command, $output, $return_var);
// 3. 检查备份是否成功
if ($return_var === 0) {
echo "Backup successful: " . $BACKUP_FILE . "\n";
// 可选:清理旧备份(保留最近30天)
$files = glob($BACKUP_DIR . '/' . $DB_NAME . '_*.sql');
usort($files, function($a, $b) {
return filemtime($a) - filemtime($b);
});
$MAX_FILES = 30; // 保留最近30个
while (count($files) > $MAX_FILES) {
$file_to_delete = array_shift($files);
if (file_exists($file_to_delete)) {
unlink($file_to_delete);
echo "Deleted old backup: " . $file_to_delete . "\n";
}
}
} else {
echo "Backup failed!\n";
echo "Command: " . $command . "\n";
print_r($output);
exit(1); // 返回非0值让cron知道失败
}
重要说明:
- 密码安全性: 将数据库密码直接写在脚本中不安全,建议创建一个
my.cnf配置文件或读取环境变量。// 更好的方式:从环境变量读取 $DB_PASS = getenv('DB_BACKUP_PASSWORD'); - mysqldump路径: 有时需指定完整路径,
/usr/bin/mysqldump。
步骤 2:配置操作系统计划任务
Linux Cron(最推荐)
- 打开crontab编辑器:
crontab -e
- 添加一条备份规则。每天凌晨2点备份:
0 2 * * * /usr/bin/php /path/to/your/backup_db.php >> /var/log/db_backup.log 2>&1
Cron表达式说明:
0 2 * * *表示每天凌晨2:00执行。- 表示每分钟执行一次(用于测试)。
0 */6 * * *表示每6小时执行一次。
- 保存文件,Cron会自动加载新任务。
Windows任务计划程序
- 打开“任务计划程序”。
- “创建基本任务...” -> 输入名称和描述 -> 设置触发器(每天”)。
- 操作选择“启动程序”,程序或脚本填写
php.exe的完整路径(如C:\php\php.exe),添加参数填写你的备份脚本路径(如C:\www\backup_db.php)。 - 完成。
常见问题与高级配置
备份文件过大怎么办?
如果数据库较大,建议压缩备份文件以节省空间并减少I/O。
在PHP脚本中,修改命令部分:
// 备份并压缩
$command = "mysqldump ... | gzip > {$BACKUP_FILE}.gz";
// 如果需要解压恢复:
// gunzip < backup.sql.gz | mysql -u root -p database_name
如何备份多个数据库?
编写脚本循环遍历数据库列表即可,或者直接使用 --all-databases 参数。
安全考虑:不要将备份文件放在Web可访问目录
- 错误示例: 放在
/var/www/html/backups/,可能被直接下载。 - 正确做法: 放在Web根目录之外,
/home/backups/或/var/backups/,并通过FTP/SFTP或专用脚本下载到远程服务器。
自动化:使用现成的库或工具
- PHP库:
spatie/db-dumper(Laravel友好) 或ifsnop/mysqldump-php(纯PHP实现,不依赖shell命令)。composer require spatie/db-dumper
然后在脚本中:
use Spatie\DbDumper\Databases\MySql; MySql::create() ->setDbName($DB_NAME) ->setUserName($DB_USER) ->setPassword($DB_PASS) ->dumpToFile($BACKUP_FILE); - 服务器管理面板: 若使用cPanel、Plesk、宝塔等面板,它们内置了数据库定期备份功能,可直接在Web界面配置,免去手动写命令。
恢复备份(验证备份是否有效)
必须定期测试恢复流程,可以使用一个测试环境验证:
mysql -u your_user -p your_database_name < /path/to/backup.sql
或者导入压缩文件:
gunzip < /path/to/backup.sql.gz | mysql -u your_user -p your_database_name
总结建议
- 首选方案: 使用操作系统Cron + 简单的Shell脚本(而非PHP脚本,因为无需占用PHP进程),直接调用
mysqldump。 - 次选方案: 如果必须在PHP项目内管理(例如云函数、共享主机没有Shell访问权限),使用纯PHP的备份库(如
ifsnop/mysqldump-php)。 - 关键动作: 务必配置日志记录(
>> /var/log/backup.log 2>&1)和失败告警(脚本内发送邮件或监控系统通知)。