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新手上路(四)
Oct 09 PHP
自动生成文章摘要的代码[PHP 版本]
Mar 20 PHP
封装一个PDO数据库操作类代码
Sep 09 PHP
php开发文档 会员收费1期
Aug 14 PHP
php实现文件下载功能的几个代码分享
May 10 PHP
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
Jun 04 PHP
PHP使用memcache缓存技术提高响应速度的方法
Dec 26 PHP
PHP获取文件相对路径的方法
Feb 26 PHP
php自定义hash函数实例
May 05 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
Dec 31 PHP
PHP获取文件扩展名的常用方法小结【五种方式】
Apr 27 PHP
yii2.0框架多模型操作示例【添加/修改/删除】
Apr 13 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
10 个经典PHP函数
2013/10/17 PHP
php源码分析之DZX1.5随机数函数random用法
2015/06/17 PHP
thinkPHP5项目中实现QQ第三方登录功能
2017/10/20 PHP
PHP输出Excel PHPExcel的方法
2018/07/26 PHP
PHP根据key删除数组中指定的元素
2019/02/28 PHP
6个常见的 PHP 安全性攻击实例和阻止方法
2020/12/16 PHP
PNG背景在不同浏览器下的应用
2009/06/22 Javascript
js创建对象的几种常用方式小结(推荐)
2010/10/24 Javascript
php 中序列化和json使用介绍
2013/07/08 Javascript
与Math.pow 相反的函数使用介绍
2014/08/04 Javascript
JS基于clipBoard.js插件实现剪切、复制、粘贴
2016/05/03 Javascript
JS获取url参数、主域名的方法实例分析
2016/08/03 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
web打印小结
2017/01/11 Javascript
koa2+vue实现登陆及登录状态判断
2019/08/15 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
js+audio实现音乐播放器
2020/09/13 Javascript
[05:06]TI4西雅图DOTA2前线报道 海涛密探LGD训练
2014/07/09 DOTA
Python中的一些陷阱与技巧小结
2015/07/10 Python
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
分享Python开发中要注意的十个小贴士
2016/08/30 Python
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
2018/05/16 Python
Python实现的文本对比报告生成工具示例
2018/05/22 Python
django认证系统实现自定义权限管理的方法
2018/07/16 Python
对python3新增的byte类型详解
2018/12/04 Python
浅谈python中真正关闭socket的方法
2018/12/18 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
纽约和芝加哥当天送花:Ode à la Rose
2019/07/05 全球购物
校领导推荐信
2013/11/01 职场文书
高中生职业规划范文
2014/03/09 职场文书
打架检讨书范文
2015/01/27 职场文书
物业保洁员岗位职责
2015/02/13 职场文书
学生犯错保证书
2015/05/09 职场文书
小学教师师德培训心得体会
2016/01/09 职场文书
2019中小学生安全过暑期倡议书
2019/06/24 职场文书
python_tkinter事件类型详情
2022/03/20 Python