当exec、passthru等函数被禁用时,如何运行mysqldump与tar命令?
解决服务商禁用exec/passthru等函数后的备份问题
方案1:用PHP内置能力实现MySQL备份(无需shell命令)
跳过mysqldump,直接通过PHP的数据库扩展(mysqli/PDO)导出数据和表结构:
- 步骤:
- 连接数据库,查询所有表名;
- 逐个获取每张表的
CREATE TABLE语句,写入备份文件; - 查询每张表的所有数据,转换成
INSERT语句追加到备份文件。
- 简化代码示例:
<?php $dbHost = 'localhost'; $dbUser = 'your_user'; $dbPass = 'your_pass'; $dbName = 'your_db'; $backupFile = './backup_' . date('YmdHis') . '.sql'; // 连接数据库 $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); if (!$conn) die('数据库连接失败'); // 获取所有表 $tables = mysqli_query($conn, 'SHOW TABLES'); $handle = fopen($backupFile, 'w'); while ($tableRow = mysqli_fetch_row($tables)) { $table = $tableRow[0]; // 写入建表语句 $createStmt = mysqli_query($conn, "SHOW CREATE TABLE `$table`"); $createRow = mysqli_fetch_assoc($createStmt); fwrite($handle, $createRow['Create Table'] . ";\n\n"); // 写入数据 $dataStmt = mysqli_query($conn, "SELECT * FROM `$table`"); $columnCount = mysqli_num_fields($dataStmt); while ($dataRow = mysqli_fetch_row($dataStmt)) { $insert = "INSERT INTO `$table` VALUES ("; for ($i = 0; $i < $columnCount; $i++) { $value = mysqli_real_escape_string($conn, $dataRow[$i]); $insert .= "'$value', "; } $insert = rtrim($insert, ', ') . ");\n"; fwrite($handle, $insert); } fwrite($handle, "\n"); } fclose($handle); mysqli_close($conn); ?>
方案2:用PHP ZipArchive替代tar命令
不用调用tar,直接用PHP内置的ZipArchive扩展实现文件压缩:
- 代码示例:
<?php $zip = new ZipArchive(); $zipFile = './backup_' . date('YmdHis') . '.zip'; $backupSql = './backup_20240520123456.sql'; // 替换为实际生成的SQL文件路径 if ($zip->open($zipFile, ZipArchive::CREATE) === TRUE) { $zip->addFile($backupSql, basename($backupSql)); $zip->close(); echo '压缩完成'; } else { echo '压缩失败'; } ?>
注意:需要确认服务器已启用ZipArchive扩展,若未启用可联系服务商开启。
方案3:申请服务商调整函数限制
直接提交工单给服务商,说明备份业务的必要性,申请:
- 临时开放
exec/shell_exec等函数用于备份脚本; - 添加备份脚本路径到函数白名单;
- 开放
mysqldump和tar的特定调用权限。
部分服务商支持针对特定脚本或目录放宽限制。
方案4:使用纯PHP编写的第三方备份工具
找完全基于PHP实现的开源备份工具,这类工具不依赖任何shell命令,直接下载部署即可完成备份操作。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

