// +---------------------------------------------------------------------- declare(strict_types=1); namespace ywxapp\command; use think\console\Command; use think\console\Input; use think\console\Output; use think\console\input\Option; use ywxapp\library\DbBackup; /** * 数据库备份命令(纯 PHP 实现,可直接挂到定时任务) * * 用法: * php think db:backup # 备份全部表 * php think db:backup -t member -t member_rule # 只备份指定表 * php think db:backup --part=5242880 --keep=7 # 5MB 分卷,只保留最近 7 份 * * 还原走后台「数据库备份」页面(有二次确认,比 CLI 更安全)。 * * @author ywxapp */ class DbBackupCommand extends Command { protected function configure() { $this->setName('db:backup') ->addOption('table', 't', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, '表名,可多次传入;不传=全部表') ->addOption('part', null, Option::VALUE_OPTIONAL, '分卷字节数,默认 2097152(2MB)') ->addOption('keep', null, Option::VALUE_OPTIONAL, '保留最近 N 份备份,超出按时间清理旧的') ->setDescription('数据库备份(纯 PHP 实现,可用于定时任务)'); } protected function execute(Input $input, Output $output) { $tables = array_values(array_filter((array) $input->getOption('table'))); $part = (int) ($input->getOption('part') ?: 2097152); $keep = (int) ($input->getOption('keep') ?: 0); $bak = new DbBackup(null, $part); try { $res = $bak->backup($tables); } catch (\Throwable $e) { $output->writeln('备份失败:' . $e->getMessage() . ''); return 1; } $output->writeln('备份完成'); $output->writeln(' 备份名:' . $res['name']); $output->writeln(' 分卷:' . count($res['files']) . '(' . implode(', ', $res['files']) . ')'); $output->writeln(' 表数:' . $res['tables'] . ',行数:' . $res['rows']); $output->writeln(' 大小:' . round($res['size'] / 1024, 2) . ' KB'); $output->writeln(' 目录:' . $bak->dir() . DIRECTORY_SEPARATOR . $res['name']); if ($keep > 0) { $list = $bak->backups(); $drop = array_slice($list, $keep); foreach ($drop as $item) { $bak->delete($item['name']); $output->writeln(' 清理旧备份:' . $item['name'] . ''); } } return 0; } }