function executeSqlFile($pdo, $filePath) {
// 读取SQL文件内容
$sql = file_get_contents($filePath);
if ($sql === false) {
throw new Exception("无法读取SQL文件: " . $filePath);
}
// 分割SQL语句(以分号加换行作为分隔符)
$queries = explode(";\n", $sql);
// 执行每条SQL语句
foreach ($queries as $query) {
$query = trim($query);
if (!empty($query)) {
try {
$pdo->exec($query);
} catch (PDOException $e) {
throw new Exception("执行SQL错误: " . $e->getMessage() . "\nSQL: " . $query);
}
}
}
}
// 使用示例
try {
$pdo = new PDO('mysql:host=localhost;dbname=your_database', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
executeSqlFile($pdo, 'path/to/your/file.sql');
echo "SQL文件执行成功";
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
对于大型SQL文件,使用PHP直接执行可能效率不高。更好的方法是调用系统命令行工具:
function executeSqlFileViaCommandLine($host, $user, $password, $database, $filePath) {
$command = "mysql -h $host -u $user -p'$password' $database < $filePath";
system($command, $output);
if ($output !== 0) {
throw new Exception("执行SQL文件失败");
}
}
// 使用示例
try {
executeSqlFileViaCommandLine(
'localhost',
'username',
'password',
'your_database',
'path/to/your/file.sql'
);
echo "SQL文件执行成功";
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
安全性:确保SQL文件来源可信,避免SQL注入风险
大文件处理:对于非常大的SQL文件,方法一可能会消耗大量内存,建议使用方法二
错误处理:确保有适当的错误处理机制
事务:如果需要原子性操作,可以在执行前开启事务
超时设置:对于长时间运行的SQL脚本,可能需要调整PHP的超时设置
function executeSqlFileImproved($pdo, $filePath) {
$sql = file_get_contents($filePath);
if ($sql === false) {
throw new Exception("无法读取SQL文件: " . $filePath);
}
// 移除注释
$sql = preg_replace('/--.*$/m', '', $sql); // 移除单行注释
$sql = preg_replace('/\/\*.*?\*\//s', '', $sql); // 移除多行注释
// 分割SQL语句(更智能的分割方式)
$queries = [];
$currentQuery = '';
foreach (explode("\n", $sql) as $line) {
$line = trim($line);
if (empty($line) || $line[0] == '#') {
continue;
}
$currentQuery .= ' ' . $line;
if (substr(rtrim($line), -1) === ';') {
$queries[] = trim($currentQuery);
$currentQuery = '';
}
}
// 执行SQL
foreach ($queries as $query) {
if (!empty($query)) {
try {
$pdo->exec($query);
} catch (PDOException $e) {
throw new Exception("执行SQL错误: " . $e->getMessage() . "\nSQL: " . $query);
}
}
}
}
选择哪种方法取决于你的具体需求和服务器环境。对于生产环境中的大型SQL文件,推荐使用方法二(命令行方式)。