PHPMailer发邮件后mysqli报错errno=32 Broken pipe求助
问题分析与解决办法
问题根源
你遇到的mysqli::ping(): send of 5 bytes failed with errno=32 Broken pipe错误,本质是数据库连接在邮件发送的1分钟空闲期内被服务器主动断开了。邮件循环执行时,数据库连接$con全程处于闲置状态,多数服务器会对长时间空闲的数据库连接设置超时回收机制,等你发完邮件再用ping()检测连接时,连接已经失效,导致后续插入操作失败。
具体修复方案
不要依赖ping()检测连接,直接在插入操作前重新建立数据库连接,或者在连接失效时自动重连。以下是两种可行的修改方式:
方式1:插入前重新连接数据库
替换原来的连接检测与插入代码:
// 关闭旧连接(如果存在) if (isset($con)) { $con->close(); } // 重新建立数据库连接(替换成你自己的数据库连接参数) $con = new mysqli($db_host, $db_user, $db_pass, $db_name); if ($con->connect_error) { die('数据库连接失败: ' . $con->connect_error); } // 执行插入操作(去掉@符号,避免屏蔽错误) $subject1 = mysqli_real_escape_string($con, $subject); $message1 = mysqli_real_escape_string($con, $_POST["message"]); $sendname1 = mysqli_real_escape_string($con, $sendname); $queryarchive = "INSERT INTO archived_groupemails (groupname, subject, message, sendname, datesent, numberemails) VALUES ( '$selectedgroupsl', '$subject1', '$message1', '$sendname1', NOW(), '$sent') "; $resultarchive = mysqli_query($con ,$queryarchive); // 可选:添加插入失败提示 if (!$resultarchive) { echo '归档插入失败: ' . $con->error; }
方式2:连接失效时自动重连
如果不想每次都重新初始化连接,可以修改检测逻辑,ping失败时自动重连:
// 检测连接,失败则重连 if (!$con->ping()) { $con->close(); // 重新连接(替换成你的数据库参数) $con = new mysqli($db_host, $db_user, $db_pass, $db_name); if ($con->connect_error) { die('数据库重连失败: ' . $con->connect_error); } } // 执行插入操作 $subject1 = mysqli_real_escape_string($con, $subject); $message1 = mysqli_real_escape_string($con, $_POST["message"]); $sendname1 = mysqli_real_escape_string($con, $sendname); $queryarchive = "INSERT INTO archived_groupemails (groupname, subject, message, sendname, datesent, numberemails) VALUES ( '$selectedgroupsl', '$subject1', '$message1', '$sendname1', NOW(), '$sent') "; $resultarchive = mysqli_query($con ,$queryarchive); if (!$resultarchive) { echo '归档插入失败: ' . $con->error; }
额外优化建议
- 去掉
@mysqli_query前的@符号,它会屏蔽错误信息,不利于排查问题; - 邮件循环里的
$body = "Hello $First".$body;会导致每次循环都在原有内容前追加问候语,最终邮件内容会越来越长,建议改为:// 先保存原始body $original_body = "....."; // 循环内拼接 $current_body = "Hello $First" . $original_body; $mail->Body = "<img alt=\"PHPMailer\" src=\"cid:banner\"><br><br>$current_body"; - 建议使用预处理语句替代手动转义,避免SQL注入风险:
$stmt = $con->prepare("INSERT INTO archived_groupemails (groupname, subject, message, sendname, datesent, numberemails) VALUES (?, ?, ?, ?, NOW(), ?)"); $stmt->bind_param("ssssi", $selectedgroupsl, $subject, $_POST["message"], $sendname, $sent); $stmt->execute(); $stmt->close();
内容的提问来源于stack exchange,提问作者MartinB
相关产品推荐
相关产品推荐

