PHP CLI 守護進程(如短信群發)長期運行,MySQL 重啟或網絡抖動導致「MySQL server has gone away」(錯誤 2006),單例模式下舊連接失效卻未重建,後續查詢全部失敗。
if (isset(self::$_instance) && !empty(self::$_instance)) {
return self::$_instance; // 閃斷後仍返回失效連接
}
class DB {
private static $_instance = null;
public static function get_conn($config) {
if (isset(self::$_instance) && !empty(self::$_instance)) {
return self::$_instance;
}
// ... 建立新 PDO 連接 ...
self::$_instance = $conn;
return $conn;
}
public static function query($dbconn, $sql, $params) {
$sth = $dbconn->prepare($sql);
try {
$sth->execute($params);
} catch (PDOException $e) {
echo $e->getMessage() . PHP_EOL;
self::reset_connect($e->getMessage()); // 關鍵:檢測閃斷並重置
}
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
public static function reset_connect($err_msg) {
if (strpos($err_msg, 'MySQL server has gone away') !== false) {
self::$_instance = null; // 強制下次重建
}
}
}
# 模擬閃斷 mysql.server stop && mysql.server start # 改造前:持續報錯 2006,空結果 # 改造後:當次失敗,下一次自動重連成功,業務繼續
PDO::ATTR_PERSISTENT 謹慎使用(預連接池可能殘留失效連接)。2006、2013(Lost connection)、HY000 通用錯誤。