如何使用 PHPMailer 正确附加 MySQL 数据库备份文件并发送邮件

酷浩同学_7312

酷浩同学_7312

2026-05-22

923人浏览

原创

如何使用 PHPMailer 正确附加 MySQL 数据库备份文件并发送邮件

本文详解如何在生成 PDO MySQL 数据库备份(支持 .sql 或 .sql.gz 压缩格式)后,通过 PHPMailer 成功将备份文件作为附件发送至指定邮箱,重点解决“附件未送达”这一常见问题。

本文详解如何在生成 pdo mysql 数据库备份(支持 `.sql` 或 `.sql.gz` 压缩格式)后,通过 phpmailer 成功将备份文件作为附件发送至指定邮箱,重点解决“附件未送达”这一常见问题。

在实际运维中,自动备份数据库并通过邮件通知是关键环节。但许多开发者遇到类似问题:备份文件成功生成(如 my_website_2024_05_20_14_30_22.sql.gz),却始终无法通过 PHPMailer 附加到邮件中——邮件正常发出,附件却为空。根本原因通常在于路径不一致、文件未及时关闭、或 AddAttachment() 调用时机错误。

以下为经过验证的修复要点与完整实践方案:

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载

✅ 关键修复点说明

  1. 确保 $save_string 是完整、可访问的绝对/相对路径
    原代码中 $save_string = $config['SAVE_AS'] . $config['SAVE_DIR'] . date(...), 但 $config['SAVE_DIR'] 初始化为空字符串(''),而 $save_dir = './' 未被传入配置。导致生成路径如 my_website_2024_05_20_14_30_22.sql.gz(无目录前缀),而 AddAttachment() 查找时可能因工作目录差异失败。
    ✅ 修正方式:统一使用明确路径,例如:

    $save_dir = __DIR__ . '/backups/'; // 推荐绝对路径
    if (!is_dir($save_dir)) mkdir($save_dir, 0755, true);
    $save_string = $save_dir . $file_name_prefix . date('Y_m_d_H_i_s') . ($do_compress ? '.sql.gz' : '.sql');
  2. 必须在调用 AddAttachment() 前完成文件写入并关闭句柄
    原函数中 gzclose($zp) 或 fclose($handle) 执行于 return 之前,看似正确;但若函数返回后立即调用 AddAttachment($save_string),而文件系统缓存未刷新或进程未完全释放,PHPMailer 可能读取失败。
    ✅ 强化保障:添加文件存在性与可读性校验:

    if (!file_exists($save_string) || !is_readable($save_string)) {
        throw new Exception("Backup file not found or unreadable: {$save_string}");
    }
  3. PHPMailer 配置需启用 addAttachment() 的完整路径 + 显式文件名
    AddAttachment($path) 接收两个参数:$path(本地路径)和可选的 $name(邮件中显示的文件名)。建议显式指定,避免 MIME 类型识别异常:

    $attachmentName = basename($save_string); // 如 'my_website_2024_05_20_14_30_22.sql.gz'
    if (!$mail->addAttachment($save_string, $attachmentName)) {
        echo "Attachment failed: " . $mail->ErrorInfo;
        exit;
    }
  4. 注意 PHPMailer 版本兼容性
    原代码使用旧版 class.phpmailer.php(v5.x),其方法名为 AddAttachment()(首字母大写);新版 PHPMailer(v6+)已改为 addAttachment()(小驼峰)。本文示例基于 v6.x(推荐升级),若沿用旧版,请保持方法名大小写一致。

✅ 完整整合示例(精简核心逻辑)

// 1. 生成备份(修正后的 backupDB 函数返回绝对路径)
$backup_config = [
    'DB_HOST' => $db_server,
    'DB_NAME' => $db_name,
    'DB_USERNAME' => $db_user,
    'DB_PASSWORD' => $db_pass,
    'INCLUDE_DROP_TABLE' => false,
    'SAVE_DIR' => __DIR__ . '/backups/', // ✅ 绝对路径
    'SAVE_AS' => $file_name_prefix,
    'APPEND_DATE_FORMAT' => 'Y_m_d_H_i_s',
    'TIMEZONE' => 'Asia/Kolkata',
    'COMPRESS' => true,
];

$backupPath = backupDB($backup_config); // 此函数内部应返回 $save_string(完整路径)

// 2. 发送邮件
$mail = new PHPMailer\PHPMailer\PHPMailer(true); // 启用异常抛出
try {
    $mail->isSMTP();
    $mail->Host       = constant('EMAILHOST');
    $mail->SMTPAuth   = constant('SMTPAuth');
    $mail->Username   = constant('SMTPUSERNAME');
    $mail->Password   = constant('SMTPPASSWORD');
    $mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port       = 587;

    $mail->setFrom(constant('FROMEMAIL'), constant('FROMNAME'));
    $mail->addAddress($mail_to1, $mail_to1_name);

    $mail->isHTML(true);
    $mail->Subject = '[' . constant('FROMNAME') . '] MySQL Backup - ' . date('d-M-Y H:i:s');
    $mail->Body    = "Database backup completed successfully. File attached.";

    // ✅ 关键:验证文件 + 附加
    if (!file_exists($backupPath) || !is_readable($backupPath)) {
        throw new Exception("Backup file inaccessible: {$backupPath}");
    }
    $mail->addAttachment($backupPath, basename($backupPath));

    $mail->send();
    echo "✅ Email sent with attachment: " . basename($backupPath);
} catch (Exception $e) {
    echo "❌ Mailer Error: {$mail->ErrorInfo}";
}

⚠️ 注意事项与最佳实践

  • 权限与路径安全:backups/ 目录不可置于 Web 可访问路径(如 public_html 下),防止恶意下载。建议存放于 ../private-backups/ 并设置 .htaccess 或 Nginx deny all。
  • 大文件限制:Gmail 等服务商限制附件 ≤25MB。若备份过大,考虑改用云存储(如 AWS S3)并邮件发送下载链接。
  • 错误日志:生产环境务必记录 backupDB() 和邮件发送的完整日志(含时间戳、文件大小、MD5 校验),便于审计与故障排查。
  • 资源清理:发送成功后,可选择保留或自动清理备份文件(unlink($backupPath)),避免磁盘占满。

通过以上结构化修正,即可稳定实现「自动备份 → 本地落盘 → 邮件附件发送」全链路闭环。核心在于路径可控、状态可验、调用有序——告别“邮件发了,附件没了”的隐形陷阱。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql php 数据库备份

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

10984

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

6401

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2155

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

4048

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4754

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3731

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

5337

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

4182

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

12102

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 188人学习