php PDO判断连接是否可用的实现方法


Posted in PHP onApril 03, 2017

mysql_ping() 检查到服务器的连接是否正常。如果到服务器的连接可用,则返回true,否则返回false。

但PDO不支持mysql_ping()方法,因此需要自己编写代码模拟mysql_ping()方法,检查连接是否可用。

代码如下:

<?php
/**
 * 检查连接是否可用
 * @param Link $dbconn 数据库连接
 * @return Boolean
 */
function pdo_ping($dbconn){
  try{
    $dbconn->getAttribute(PDO::ATTR_SERVER_INFO);
  } catch (PDOException $e) {
    if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){
      return false;
    }
  }
  return true;
}
?>

代码演示:

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、演示文件

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;
    }
    $result = $sth->fetchAll(PDO::FETCH_ASSOC);
    return $result;
  }

  // 重置连接
  public static function reset_connect(){
    self::$_instance = null;
  }

}
?>

test.php

<?php
require 'db.php';

// 数据库设定
$config = array(
  'host' => 'localhost',
  'dbname' => 'user',
  'user' => 'root',
  'password' => '',
  'pconnect' => 0,
  'charset' => ''
);

// 循环执行
while(true){

  // 创建数据连接
  $dbconn = DB::get_conn($config);

  // 判断连接是否有效
  $status = pdo_ping($dbconn);

  if($status){
    echo 'connect ok'.PHP_EOL;
  }else{
    echo 'connect failure'.PHP_EOL;

    // 重置连接
    DB::reset_connect();
    $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);

}

/**
 * 检查连接是否可用
 * @param Link $dbconn 数据库连接
 * @return Boolean
 */
function pdo_ping($dbconn){
  try{
    $dbconn->getAttribute(PDO::ATTR_SERVER_INFO);
  } catch (PDOException $e) {
    if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){
      return false;
    }
  }
  return true;
}
?>

4、执行

在php cli模式下执行test.php,然后马上执行mysql.server stop 与 mysql.server start 模拟闪断

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

执行输出:

connect ok
Array
(
  [0] => Array
    (
      [id] => 2
      [name] => xfdipzone
    )

)
sleep 10

connect failure
Array
(
  [0] => Array
    (
      [id] => 3
      [name] => terry
    )

)
sleep 10

connect ok
Array
(
  [0] => Array
    (
      [id] => 3
      [name] => terry
    )

)
sleep 10

可以看到闪断后,pdo_ping()返回false,连接失败,然后调用自动重连,保证后面的查询能继续执行。

以上这篇php PDO判断连接是否可用的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php在线生成ico文件的代码
Oct 09 PHP
PHP 判断变量类型实现代码
Oct 23 PHP
PHP URL参数获取方式的四种例子
Feb 28 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
Jul 22 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
Oct 20 PHP
PHP模块memcached使用指南
Dec 08 PHP
使用GDB调试PHP代码,解决PHP代码死循环问题
Mar 02 PHP
php实现转换ubb代码的方法
Jun 18 PHP
php实现购物车功能(下)
Jan 05 PHP
thinkphp3.x中变量的获取和过滤方法详解
May 20 PHP
Netbeans 8.2与PHP相关的新特性介绍
Oct 08 PHP
php弹出提示框的是实例写法
Sep 26 PHP
php 调用ffmpeg获取视频信息的简单实现
Apr 03 #PHP
php文件包含目录配置open_basedir的使用与性能详解
Apr 03 #PHP
thinkphp关于简单的权限判定方法
Apr 03 #PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
Apr 01 #PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
Apr 01 #PHP
thinkphp自定义权限管理之名称判断方法
Apr 01 #PHP
浅谈ThinkPHP中initialize和construct的区别
Apr 01 #PHP
You might like
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php之字符串变相相减的代码
2007/03/19 PHP
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
PHP中使用CURL模拟登录并获取数据实例
2014/07/01 PHP
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
实例说明js脚本语言和php脚本语言的区别
2019/04/04 PHP
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
使用js画图之正弦曲线
2015/01/12 Javascript
javascript中动态函数用法实例分析
2015/05/14 Javascript
javascript事件冒泡和事件捕获详解
2015/05/26 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
Angular4实现动态添加删除表单输入框功能
2017/08/11 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
详解Vue源码学习之callHook钩子函数
2018/07/25 Javascript
Vue 的 v-model用法实例
2020/11/23 Vue.js
Python使用 Beanstalkd 做异步任务处理的方法
2018/04/24 Python
Python多项式回归的实现方法
2019/03/11 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
Tensorflow加载Vgg预训练模型操作
2020/05/26 Python
python爬虫实例之获取动漫截图
2020/05/31 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
匡威英国官网:Converse英国
2018/12/02 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
Yahoo-PHP面试题1
2016/07/20 面试题
财务主管岗位职责
2014/02/28 职场文书
2014年大学生党课心得体会范文
2014/03/29 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
消防志愿者活动方案
2014/08/23 职场文书
SpringBoot+Vue+JWT的前后端分离登录认证详细步骤
2021/09/25 Java/Android
angular4实现带搜索的下拉框
2022/03/25 Javascript
PHP正则表达式之RCEService回溯
2022/04/11 PHP