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 相关文章推荐
用Zend Encode编写开发PHP程序
Oct 09 PHP
建立文件交换功能的脚本(三)
Oct 09 PHP
php仿discuz分页效果代码
Oct 02 PHP
ThinkPHP之A方法实例讲解
Jun 20 PHP
PHP SPL标准库中的常用函数介绍
May 11 PHP
php实现修改新闻时删除图片的方法
May 12 PHP
ThinkPHP路由详解
Jul 27 PHP
thinkPHP中create方法与令牌验证实例浅析
Dec 08 PHP
Zend Framework开发入门经典教程
Mar 23 PHP
使用正则去除php代码中的注释方法
Nov 03 PHP
thinkPHP5.0框架自动加载机制分析
Mar 18 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 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
编写PHP的安全策略
2006/10/09 PHP
PHP+FLASH实现上传文件进度条相关文件 下载
2007/07/21 PHP
PHP笔记之:基于面向对象设计的详解
2013/05/14 PHP
Yii2前后台分离及migrate使用(七)
2016/05/04 PHP
PHP实现中国公民身份证号码有效性验证示例代码
2017/05/03 PHP
PHP实现图片压缩
2020/09/09 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
用document.documentElement取代document.body的原因分析
2009/11/12 Javascript
向大师们学习Javascript(视频与PPT)
2009/12/27 Javascript
JQuery跨Iframe选择实现代码
2010/08/19 Javascript
javascript中的变量作用域以及变量提升详细介绍
2013/10/24 Javascript
封装好的js判断操作系统与浏览器代码分享
2015/01/09 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
Bootstrap CSS组件之面包屑导航(breadcrumb)
2016/12/17 Javascript
vue 1.x 交互实现仿百度下拉列表示例
2017/10/21 Javascript
jQuery 获取除某指定对象外的其他对象 ( :not() 与.not())
2018/10/10 jQuery
VUE安装使用教程详解
2019/06/03 Javascript
layui实现把数据表格时间戳转换为时间格式的例子
2019/09/12 Javascript
Vue实现简单计算器案例
2020/02/25 Javascript
python动态性强类型用法实例
2015/05/09 Python
python中实现指定时间调用函数示例代码
2017/09/08 Python
Python爬虫获取整个站点中的所有外部链接代码示例
2017/12/26 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
python中的itertools的使用详解
2020/01/13 Python
python实现密度聚类(模板代码+sklearn代码)
2020/04/27 Python
详解scrapy内置中间件的顺序
2020/09/28 Python
Python安装并操作redis实现流程详解
2020/10/13 Python
印度在线内衣和时尚目的地:Zivame
2017/09/28 全球购物
单身联谊活动方案
2014/01/29 职场文书
大学军训感言300字
2014/03/09 职场文书
在职党员进社区活动总结
2014/07/05 职场文书
观后感格式
2015/06/19 职场文书
用Python制作灯光秀短视频的思路详解
2021/04/13 Python
JavaScript实现淘宝商品图切换效果
2021/04/29 Javascript
Python 匹配文本并在其上一行追加文本
2022/05/11 Python