Comment se reconnecter automatiquement lorsque la connexion MySQL est interrompue

jacklove
Libérer: 2023-03-31 06:20:02
original
2323 Les gens l'ont consulté

Utilisez PHP comme programme exécuté en arrière-plan (comme les SMS en masse) et exécutez PHP en mode cli. PHP doit se connecter à MySQL pour effectuer le traitement de la base de données en boucle.
Lorsque la connexion mysql est interrompue, l'exécution ultérieure de la boucle échouera.

Nous devons concevoir une méthode qui puisse se reconnecter automatiquement lorsque MySQL est déconnecté, afin que les programmes suivants puissent s'exécuter normalement.

1. Créer un tableau de données de test

CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Copier après la connexion

2. Insérer les données de test

insert into user(name) values('fdipzone'),('xfdipzone'),('terry');mysql> select * from user;
+----+-----------+| id | name      |
+----+-----------+|  1 | fdipzone  |
|  2 | xfdipzone ||  3 | terry     |
+----+-----------+
Copier après la connexion

3. 🎜 >

db.php

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }
}?>
Copier après la connexion
test.php

4. étapes

<?phprequire &#39;db.php&#39;;// 数据库设定$config = array(    &#39;host&#39; => 'localhost',    'dbname' => 'user',    'user' => 'root',    'password' => '',    'pconnect' => 0,    'charset' => '');// 循环执行while(true){    // 创建数据连接
    $dbconn = DB::get_conn($config);    // 执行查询
    $sqlstr = 'select * from user where id=?';    $condparam = array(mt_rand(1,3));    $data = DB::query($dbconn, $sqlstr, $condparam);
    print_r($data);    // 延时10秒
    echo 'sleep 10'.PHP_EOL.PHP_EOL;
    sleep(10);
}?>
Copier après la connexion
Exécutez test.php en mode php cli, puis exécutez immédiatement mysql.server stop et mysql.server start pour simuler une interruption flash

Vous pouvez voir que la base de données ne peut pas être reconnecté après une interruption du flash, le programme suivant ne peut pas être exécuté.

mysql.server stopShutting down MySQL
.. SUCCESS! 
mysql.server start
Starting MySQL
 SUCCESS!
Copier après la connexion

5. Ajoutez un mécanisme de reconnexion

Array
(
    [0] => Array
        (
            [id] => 3
            [name] => terry
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10...
Copier après la connexion

Après l'interruption, car la valeur de self::$_instance existe, l'appel de get_conn ne se reconnectera pas, mais utiliser save connection est traité.

if(isset(self::$_instance) && !empty(self::$_instance)){    return self::$_instance;
}
Copier après la connexion
Cela signifie en fait que lorsque la connexion existe, il n'est pas nécessaire de créer à nouveau une connexion mysql, réduisant ainsi le nombre de connexions mysql.

Il est donc nécessaire d'effacer la valeur de self::$_instance après l'interruption afin que la connexion puisse être réacquise la prochaine fois sans utiliser la connexion à la base de données qui a été créée mais expirée.

La méthode d'amélioration est la suivante :

Ajoutez la méthode reset_connect, qui est appelée lorsqu'une erreur survient. Si l'erreur de jugement est
Le serveur MySQL a disparu, la connexion à la base de données existante sera effacée. Après l'effacement, MySQL sera reconnecté la prochaine fois. Le fichier php modifié est le suivant :

db.php
6. Effectuez à nouveau l'exécution flash

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;            self::reset_connect($e->getMessage()); // 出错时调用重置连接
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }    // 重置连接
    public static function reset_connect($err_msg){
        if(strpos($err_msg, 'MySQL server has gone away')!==false){            self::$_instance = null;
        }
    }
}?>
Copier après la connexion
Vous pouvez voir l'effet amélioré. Après l'interruption, l'exécution en cours échouera, mais une nouvelle connexion peut être recréée pour continuer l'exécution.

Cet article explique les connaissances pertinentes sur la méthode de reconnexion automatique lorsque la connexion MySQL est interrompue. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois.

Array(
    [0] => Array
        (
            [id] => 2
            [name] => xfdipzone
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray(
)
sleep 10Array(
    [0] => Array
        (
            [id] => 1
            [name] => fdipzone
        )
)
sleep 10...
Copier après la connexion
Recommandations associées :

php implémente une classe pour convertir les numéros d'entité HTML et les chaînes non-ASCII


php selon l'identifiant auto-croissant crée une classe de numéros unique


À propos de mysql La méthode d'affichage du fichier de configuration actuellement utilisé my.cnf est expliquée

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal