方法一:使用 PHP 执行命令行

<?php
// 数据库配置
$dbHost = 'localhost';
$dbUser = 'username';
$dbPass = 'password';
$dbName = 'database_name';
$tableName = 'table_name'; // 如果要导出所有表,设为空或 null

// 输出文件配置
$sqlFileName = 'backup_' . date('Ymd_His') . '.sql';
$zipFileName = 'backup_' . date('Ymd_His') . '.zip';

// 构建 mysqldump 命令
$command = "mysqldump -h $dbHost -u $dbUser -p'$dbPass' $dbName";
if (!empty($tableName)) {
    $command .= " $tableName";
}

// 执行命令并直接压缩
$command .= " | zip $zipFileName -";

// 执行命令
system($command, $output);

if ($output === 0) {
    echo "数据库备份成功,ZIP文件已创建: $zipFileName";
} else {
    echo "数据库备份失败";
}
?>

方法二:纯 PHP 实现(不依赖命令行)

<?php
// 数据库配置
$dbHost = 'localhost';
$dbUser = 'username';
$dbPass = 'password';
$dbName = 'database_name';
$tableName = 'table_name'; // 如果要导出所有表,设为空或 null

// 输出文件配置
$sqlFileName = 'backup_' . date('Ymd_His') . '.sql';
$zipFileName = 'backup_' . date('Ymd_His') . '.zip';

// 连接数据库
$conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

// 获取表结构
function getTableStructure($conn, $tableName) {
    $structure = "";
    $result = $conn->query("SHOW CREATE TABLE `$tableName`");
    if ($result) {
        $row = $result->fetch_assoc();
        $structure = $row['Create Table'] . ";\n\n";
    }
    return $structure;
}

// 获取表数据
function getTableData($conn, $tableName) {
    $data = "";
    $result = $conn->query("SELECT * FROM `$tableName`");
    
    if ($result->num_rows > 0) {
        $data .= "-- 数据导出: `$tableName`\n";
        $data .= "INSERT INTO `$tableName` VALUES \n";
        
        $rows = array();
        while ($row = $result->fetch_assoc()) {
            $values = array();
            foreach ($row as $value) {
                $values[] = "'" . $conn->real_escape_string($value) . "'";
            }
            $rows[] = "(" . implode(", ", $values) . ")";
        }
        $data .= implode(",\n", $rows) . ";\n\n";
    }
    return $data;
}

// 创建 SQL 文件内容
$sqlContent = "-- MySQL 数据导出\n";
$sqlContent .= "-- 生成时间: " . date('Y-m-d H:i:s') . "\n\n";

if (!empty($tableName)) {
    // 导出单个表
    $sqlContent .= getTableStructure($conn, $tableName);
    $sqlContent .= getTableData($conn, $tableName);
} else {
    // 导出所有表
    $tables = $conn->query("SHOW TABLES");
    while ($table = $tables->fetch_array()) {
        $tableName = $table[0];
        $sqlContent .= getTableStructure($conn, $tableName);
        $sqlContent .= getTableData($conn, $tableName);
    }
}

// 创建 ZIP 文件
$zip = new ZipArchive();
if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) {
    $zip->addFromString($sqlFileName, $sqlContent);
    $zip->close();
    echo "数据库备份成功,ZIP文件已创建: $zipFileName";
} else {
    echo "无法创建 ZIP 文件";
}

$conn->close();
?>

方法三:使用 PHP 类和更高效的方式

<?php
class MySQLBackup {
    private $dbHost;
    private $dbUser;
    private $dbPass;
    private $dbName;
    private $conn;
    
    public function __construct($host, $user, $pass, $db) {
        $this->dbHost = $host;
        $this->dbUser = $user;
        $this->dbPass = $pass;
        $this->dbName = $db;
        $this->connect();
    }
    
    private function connect() {
        $this->conn = new mysqli($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName);
        if ($this->conn->connect_error) {
            die("连接失败: " . $this->conn->connect_error);
        }
    }
    
    public function backupToZip($tables = '*', $zipFileName = null) {
        if ($zipFileName === null) {
            $zipFileName = 'backup_' . date('Ymd_His') . '.zip';
        }
        
        $sqlFileName = pathinfo($zipFileName, PATHINFO_FILENAME) . '.sql';
        $tempFile = tempnam(sys_get_temp_dir(), 'sql_');
        
        // 打开临时文件
        $handle = fopen($tempFile, 'w');
        
        // 写入头部信息
        fwrite($handle, "-- MySQL 数据导出\n");
        fwrite($handle, "-- 生成时间: " . date('Y-m-d H:i:s') . "\n\n");
        
        // 获取所有表
        if ($tables == '*') {
            $tables = array();
            $result = $this->conn->query("SHOW TABLES");
            while ($row = $result->fetch_row()) {
                $tables[] = $row[0];
            }
        } else {
            $tables = is_array($tables) ? $tables : explode(',', $tables);
        }
        
        // 循环处理每个表
        foreach ($tables as $table) {
            // 获取表结构
            $result = $this->conn->query("SHOW CREATE TABLE `$table`");
            $row = $result->fetch_assoc();
            fwrite($handle, "-- 表结构: `$table`\n");
            fwrite($handle, $row['Create Table'] . ";\n\n");
            
            // 获取表数据
            $result = $this->conn->query("SELECT * FROM `$table`");
            if ($result->num_rows > 0) {
                fwrite($handle, "-- 数据导出: `$table`\n");
                fwrite($handle, "INSERT INTO `$table` VALUES \n");
                
                $first = true;
                while ($row = $result->fetch_assoc()) {
                    if (!$first) {
                        fwrite($handle, ",\n");
                    }
                    $first = false;
                    
                    $values = array();
                    foreach ($row as $value) {
                        $values[] = "'" . $this->conn->real_escape_string($value) . "'";
                    }
                    fwrite($handle, "(" . implode(", ", $values) . ")");
                }
                fwrite($handle, ";\n\n");
            }
        }
        
        fclose($handle);
        
        // 创建 ZIP 文件
        $zip = new ZipArchive();
        if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) {
            $zip->addFile($tempFile, $sqlFileName);
            $zip->close();
            unlink($tempFile); // 删除临时文件
            return $zipFileName;
        } else {
            unlink($tempFile); // 删除临时文件
            return false;
        }
    }
}

// 使用示例
$backup = new MySQLBackup('localhost', 'username', 'password', 'database_name');
$result = $backup->backupToZip('*'); // 导出所有表
// $result = $backup->backupToZip('users,products'); // 导出指定表

if ($result) {
    echo "备份成功,文件已保存为: " . $result;
} else {
    echo "备份失败";
}
?>

注意事项

  1. 确保 PHP 已安装并启用了 Zip 扩展(extension=zip.so 或 extension=zip.dll

  2. 确保 PHP 有权限写入目标目录

  3. 对于大型数据库,方法二和方法三可能比方法一慢

  4. 方法一需要服务器允许执行系统命令

  5. 生产环境中应考虑安全措施,如验证用户权限、限制访问等

选择哪种方法取决于你的具体需求和环境限制。方法一最简单高效,但需要服务器权限;方法二和方法三更可控,但性能可能稍差。