>  기사  >  데이터 베이스  >  PHP가 MySql_MySQL에 연결할 때 자동으로 다시 연결하는 방법

PHP가 MySql_MySQL에 연결할 때 자동으로 다시 연결하는 방법

WBOY
WBOY원래의
2016-09-15 11:14:481175검색

PHP를 백그라운드 실행 프로그램(예: 대량 SMS)으로 사용하고 PHP를 cli 모드에서 실행합니다. PHP는 루프에서 데이터베이스 처리를 수행하기 위해 MySQL에 연결해야 합니다.

mysql 연결이 중단되면 이후 루프 실행이 실패합니다.

후속 프로그램이 정상적으로 실행될 수 있도록 mysql 연결이 끊길 때 자동으로 다시 연결될 수 있는 방법을 설계해야 합니다.

1. 테스트 데이터 테이블을 생성합니다

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. 테스트 데이터 삽입

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

3. 백그라운드에서 실행되는 PHP 파일

db.php

<&#63;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['host'];
$dbname = $config['dbname'];
$dbuser = $config['user'];
$dbpasswd = $config['password'];
$pconnect = $config['pconnect'];
$charset = $config['charset'];
$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;
}
}
&#63;>

test.php

<&#63;php
require 'db.php';
// 数据库设定
$config = array(
'host' => 'localhost',
'dbname' => 'user',
'user' => 'root',
'password' => '',
'pconnect' => 0,
'charset' => ''
);
// 循环执行
while(true){
// 创建数据连接
$dbconn = DB::get_conn($config);
// 执行查询
$sqlstr = 'select * from user where id=&#63;';
$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);
}
&#63;>

4. 단계 실행

php cli 모드에서 test.php를 실행한 후 즉시 mysql.server stop 및 mysql.server start를 실행하여 플래시 중단을 시뮬레이션합니다

mysql.server stop
Shutting down MySQL
.. SUCCESS! 
mysql.server start
Starting MySQL
SUCCESS!

보시다시피 중단 후에는 데이터베이스를 다시 연결할 수 없으며 후속 프로그램을 실행할 수 없습니다.

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

5. 재연결 메커니즘 추가

if(isset(self::$_instance) && !empty(self::$_instance)){
return self::$_instance;
}

중단 후 self::$_instance 값이 존재하므로 get_conn을 호출하면 다시 연결되지 않고 저장된 연결을 사용하여 처리합니다.

실제로는 연결이 존재하면 mysql 연결을 다시 생성할 필요가 없으므로 mysql 연결 수가 줄어듭니다.

따라서 생성되었으나 실패한 데이터베이스 연결을 사용하지 않고 다음에 연결을 다시 얻을 수 있도록 중단 후 self::$_instance 값을 지워야 합니다.

개선 방법은 다음과 같습니다.

오류 발생 시 호출되는 Reset_connect 메소드를 추가합니다. 오류가 MySQL 서버가 사라진 것으로 판단되면 기존 데이터베이스 연결이 지워지고 다음에 MySQL이 다시 연결됩니다.

수정된 php 파일은 다음과 같습니다.

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['host'];
$dbname = $config['dbname'];
$dbuser = $config['user'];
$dbpasswd = $config['password'];
$pconnect = $config['pconnect'];
$charset = $config['charset'];
$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;
}
}
}
?>

6. 플래시 실행을 다시 수행합니다

중단 이후에는 현재 실행이 실패하지만 후속 실행이 다시 생성되고 새로운 연결이 계속되는 향상된 효과를 볼 수 있습니다.

Array
(
[0] => Array
(
[id] => 2
[name] => xfdipzone
)
)
sleep 10
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10
Array
(
[0] => Array
(
[id] => 1
[name] => fdipzone
)
)
sleep 10
...

위 내용은 PHP가 MySql에 연결될 때 자동으로 다시 연결하는 방법을 편집자가 소개한 방법입니다. 질문이 있는 경우 메시지를 남겨주시면 편집자가 답변해 드리겠습니다. 당신은 시간에. 홈페이지에 대한 귀하의 지원에 진심으로 감사드립니다!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.