这个数据库类主要处理了单例模式下创建数据库对象时,如果有两次较长时间的间隔去执行sql操作,再次处理会出现连接失败的问题,利用一个cache数组存放pdo对象与时间戳,把两次执行之间的时间进行了比较,如果间隔超过了10秒就再次new PDO创建连接,没有超过的情况下会继续使用原来的连接,并且因为每次使用后会使连接续期,cache数组里的时间戳也进行了续期.
每次执行操作都会从cache数组中获取下连接,多次执行不超过10秒的情况下,只会有一个连接

代码中实现读写分离,判断sql语句前面6个字符是select的就查询从库,其余操作查询主库.主库和从库就是分别在配置数组中0和1创建不同的PDO对象连接

代码如下:

<?php
class SinaPdoAdapter{
const MASTER = 0;
const SLAVE = 1;
const DEFAULT_CACHE_EXPIRETIME = 10;
private static $options = array(
PDO::ATTR_AUTOCOMMIT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
//PDO::ATTR_PERSISTENT => true,
);
private $dsn = null;
private $username = null;
private $password = null;
private $timeout = null;
private $charset = null;
private $conns = array();
private $conn = null;
private $stmt = null;
private static $obj=null;
private function __construct($dsn, $username, $password, $timeout = null, $charset = null){
$this->dsn = $dsn;
if (!is_array($username)) {
$this->username = array($username);
} else {
$this->username = $username;
}
if (!is_array($password)) {
$this->password = array($password);
} else {
$this->password = $password;
}
$this->timeout = intval($timeout);
$this->charset = $charset;
}
private function getConnection($id = self::MASTER){
if (!isset($this->dsn[$id])) {
$id = self::MASTER;
}
$conn = $this->getCachedConn($id);
if ($conn) {
return $conn;
}
$opts = self::$options;
if ($this->timeout > 0) {
$opts[PDO::ATTR_TIMEOUT] = $this->timeout;
}
$username = isset($this->username[$id]) ? $this->username[$id] : $this->username[self::MASTER];
$password = isset($this->password[$id]) ? $this->password[$id] : $this->password[self::MASTER];
$conn = new PDO($this->dsn[$id], $username, $password, $opts);
$this->cacheConn($id, $conn);
if ($this->charset) {
$conn->exec('set names ' . $this->charset);
}
return $conn;
} public function execute($sql, $params = array()){
$cmd = substr($sql, 0, 6);
if (strcasecmp($cmd, 'select') === 0) {
$conn = $this->getConnection(self::SLAVE);
} else {
$conn = $this->getConnection(self::MASTER);
}
$stmt = $conn->prepare($sql);
$stmt->execute($params);
$this->stmt = $stmt;
$this->conn = $conn;
} public function fetch(){
return $this->stmt->fetch();
} public function fetchAll(){
return $this->stmt->fetchAll();
}
public function lastInsertId(){
return $this->conn->lastInsertId();
}
public function rowCount(){
return $this->stmt->rowCount();
} public static function getInstance($conf){
if(self::$obj == null){
self::$obj = new self($conf->dsn,$conf->username,$conf->password,$conf->timeout,$conf->charset);
}
return self::$obj;
} private function getCachedConn($id){
if (!isset($this->conns[$id])) {
return null;
}
list($conn, $timeout) = $this->conns[$id];
if (time() < $timeout) {
$this->cacheConn($id, $conn);
return $conn;
} else {
return null;
}
}
private function cacheConn($id, $conn){
$timeout = time();
if ($this->timeout) {
$timeout += $this->timeout;
} else {
$timeout += self::DEFAULT_CACHE_EXPIRETIME;
}
$this->conns[$id] = array($conn, $timeout);
}
} $config=new stdClass();
$config->dsn=array(
"mysql:host=127.0.0.1;port=3306;dbname=surframe",//主库
"mysql:host=127.0.0.2;port=3306;dbname=surframe"//从库
);
$config->username=array(
'root', 'root',
);
$config->password=array(
'taoshihan1', 'taoshihan1',
);
$config->timeout=10;
$config->charset="utf8"; $db=SinaPdoAdapter::getInstance($config);
$db->execute("select * from admin_users");//使用的从库
$rows=$db->fetchAll();
var_dump($db); $db=SinaPdoAdapter::getInstance($config);
$db->execute("select * from admin_users");//使用的从库
$rows=$db->fetchAll();
var_dump($db);

[PHP] PHP PDO与mysql的连接单例防止超时情况处理的更多相关文章

  1. java设计模式——单例(Singleton)模式

    在某些场景,你需要找到一个承担职责的对象,并且这个对象是他所属类的唯一实例.此时可以使用单例模式. 单例模式的意图是为了确保一个类有且仅有一个实例,并为他提供一个全局的访问点.创建一个担当独一无二角色 ...

  2. 设置模式之单例模式(附上一个Objective-C编写的播放音乐的单例类)

    在查阅Cocoa Touch开发文档时,会发现框架中随处可见的大量单例类,比如说,UIApplication.NSFileManager 等. UIApplication 框架中极为常用的一个单例类, ...

  3. java 中的懒汉单例和饿汉单例模式

    //-------------------------------------------------------------饿汉模式--开始----------------------------- ...

  4. spring中的单例和多例

    单例 对象在整个系统中只有一份,所有的请求都用一个对象来处理,如service和dao层的对象一般是单例的. 为什么使用单例:因为没有必要每个请求都新建一个对象的时候,浪费CPU和内存. 多例 对象在 ...

  5. Java并发笔记——单例与双重检测

    单例模式可以使得一个类只有一个对象实例,能够减少频繁创建对象的时间和空间开销.单线程模式下一个典型的单例模式代码如下: ① class Singleton{ private static Single ...

  6. php中使用mysqli和pdo扩展,测试连接mysql数据库的效率。

    <?php /** * 测试pdo和mysqli的连接效率,各连接100次mysql数据库 */ header("Content-type:text/html;charset=utf8 ...

  7. [PHP] PDO对象与mysql的连接超时

    在php中每一个new的PDO对象,都会去连接mysql,都会创建一条tcp连接.当pdo对象赋予的变量是一个的时候,那么他只会保持一个tcp连接,没有被引用的对象连接会直接断掉.如果不对这个对象进行 ...

  8. MySQL数据库单例连接简单实现(MySQL扩展)

    <?php /** * MySQL数据库单例实现 * * @author shizq at 2015-04-22 * */ final class MySQLFactory { private ...

  9. PDO之MySql持久化自动重连导致内存溢出

    前言 最近项目需要一个常驻内存的脚本来执行队列程序,脚本完成后发现Mysql自动重连部分存在内存溢出,导致运行一段时间后,会超出PHP内存限制退出 排查 发现脚本存在内存溢出后排查了一遍代码,基本确认 ...

随机推荐

  1. 利用Azure虚拟机安装Dynamics 365 Customer Engagement之十一:SQL Server配置Always On后D365的配置更改

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  2. This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value

    iOS10 11之后遇到这种报错的小伙伴们请注意啦: 你会发现网上一大堆博客和论坛都是让你在  Info.plist 里面要涉及隐私数据时要添加一句“提示语”.于是打开 Info.plist,点击 + ...

  3. 这些Android系统样式中的颜色属性你知道吗?

    Android 系统样式中的颜色属性 推荐阅读看完后彻底搞清楚Android中的 Attr . Style .Theme 几个常用的颜色属性 先放上一张经典的图片,图片来自网络. 这张图在网上很是流传 ...

  4. 基于opencv -python--银行卡识别

    import cv2 def sort_contours(cnts, method="left-to-right"): reverse = False i = 0 if metho ...

  5. Android 组件化最佳实践 ARetrofit 原理

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/TXFt7ymgQXLJyBOJL8F6xg作者:朱壹飞 ARetrofit 是一款针对Android ...

  6. 一文解读MPA/SPA(转)

    应用模式 模式示意图 多页面应用 每一次页面跳转的时候,后台服务器都会返回一个新的html文档,这种类型的网站也就是多页网站,也叫多页应用. 页面跳转: 返回HTML优点: 首屏时间快,SEO效果好缺 ...

  7. tomcat修改进程名称

    1.window平台: 打开tomcat_home\bin\setclasspath.bat文件,找到set _RUNJAVA=”%JRE_HOME%\bin\java”这一行. 将该行注释掉 ,然后 ...

  8. Centos7系统Docker安装

    目录 前期说明 安装步骤 1.官网中文安装参考手册 2.确定你是CentOS7及以上版本 3.yum安装gcc相关 4.卸载旧版本 5.安装需要的软件包 6.设置stable镜像仓库 7.更新yum软 ...

  9. ​Linux环境下搭建禅道管理工具-包含软件资源

    ​Linux环境下搭建禅道管理工具 1:百度云盘下载: 禅道--链接: https://pan.baidu.com/s/1Stu7nOZVIPO5TnpJWjWtiQ 提取码:dnik CentOs操 ...

  10. Codeforces Round #598 (Div. 3)

    传送门 A. Payment Without Change 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/4 21:19:19 */ #i ...