这个数据库类主要处理了单例模式下创建数据库对象时,如果有两次较长时间的间隔去执行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. Ubantu 安装SSH

    1.检查是否安装SSH dpkg --get-selections | grep ssh 一般情况下Ubantu 默认集成 openssh-client,但要用sftp的话还需要安装openssh-s ...

  2. 获取当前Linux的外网地址

    有时候我们在测试配置外网IP是不是成功时,我们需要使用一些命令,使用 ssh 登录可以查看ip, 还有一种可以使用命令: curl ifconfig.me 进行方便获取,公网IP:真的是非常好的服务: ...

  3. 8. Vue - Router

    一.Vue Router 的使用 JavaScript: 1.创建组件:创建单页面应用需要渲染的组件 2.创建路由:创建VueRouter实例 3.映射路由:调用VueRouter实例的map方法 4 ...

  4. 201871010112-梁丽珍《面向对象程序设计(java)》第十二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  5. 算法问题实战策略 SORTGAME

    地址 https://algospot.com/judge/problem/read/SORTGAME 解答 常规BFS是会超时的  按照书上的提示 应该是打表(居然还有提倡打表的题目) tle 代码 ...

  6. Centos7下安装Relion

    目录 1.Virtual Box 1.1下载Virtual Box 1.2安装Virtual Box 2.Centos7 2.1下载Centos7 2.2安装Centos7 2.2.1配置虚拟机 2. ...

  7. A1071 Speech Patterns (25 分)

    一.技术总结 开始拿到这道题目时,思考的是我该如何区分它们每一个单词,不知道这里还是要学习得知在cctype头文件中有一个函数用于查看是否为0~9.a~z.A~Z,就是isalnum(),又因为题目中 ...

  8. Optical Flow 发展历程 (1)

    Optical flow estimation Traditional Method Variational approach TVL-1 [1] Deep Method Supervised Flo ...

  9. IT兄弟连 Java语法教程 流程控制语句 控制循环结构1

    Java语言没有提供goto语句来控制程序的跳转,这种做法提高了程序流程控制的可读性,但降低了程序流程控制的灵活性.为了弥补这种不足,Java提供了continue和break来控制循环结构.除此之外 ...

  10. 【Linux命令】系统状态检测命令8个(ifconfig、uname、uptime、free、who、last、history、sosreport)

    目录 ifconfig获取网卡配置信息 uname查看系统内核版本 uptime查看系统的负载信息 free查看内存信息 who查看当前主机用户的终端信息 last查看系统的登录记录 history查 ...