Maison  >  Article  >  développement back-end  >  Comment se reconnecter automatiquement lorsque la connexion MySQL est interrompue

Comment se reconnecter automatiquement lorsque la connexion MySQL est interrompue

jacklove
jackloveoriginal
2018-06-08 23:11:422324parcourir

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;

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     |
+----+-----------+

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;
    }
}?>
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);
}?>
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!

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...

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;
}
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;
        }
    }
}?>
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...
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!

Déclaration:
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