@@ -31,7 +31,7 @@ class Connection
3131 PDO ::ATTR_ERRMODE => PDO ::ERRMODE_EXCEPTION ,
3232 PDO ::ATTR_STRINGIFY_FETCHES => false , //禁止提取的时候将数值转换为字符串
3333 PDO ::ATTR_EMULATE_PREPARES => false , //禁止模拟预处理语句
34- PDO ::ATTR_CASE => PDO ::CASE_NATURAL ,
34+ PDO ::ATTR_CASE => PDO ::CASE_NATURAL , //列名原样返回,不做大小写转换
3535 PDO ::ATTR_TIMEOUT => 1 , //连接超时秒数
3636 ),
3737 'slave ' => array (/*
@@ -47,8 +47,9 @@ class Connection
4747 ),*/
4848 ),
4949
50- //服务器超时并关闭连接时,是否自动重连 (常驻内存时需要开启)
51- 'serverGoneAwayReconnect ' => false ,
50+ //服务器超时并关闭连接时,是否自动重连 (常驻内存时按需开启)
51+ //MySQL server has gone away
52+ 'reconnect ' => false ,
5253 );
5354
5455 //连接类型
@@ -88,23 +89,6 @@ public function setReadPdo(PDO $pdo)
8889 $ this ->readPdo = $ pdo ;
8990 }
9091
91- protected function makePdo (array $ config )
92- {
93- if (isset ($ config ['dsn ' ])) {
94- $ dsn = $ config ['dsn ' ];
95- } else {
96- $ dsn = 'mysql:host= ' . $ config ['host ' ] . ';dbname= ' . $ config ['database ' ];
97- }
98-
99- $ pdo = new PDO ($ dsn , $ config ['username ' ], $ config ['password ' ], $ config ['options ' ]);
100-
101- if (strpos ($ dsn , 'mysql: ' ) === 0 ) {
102- $ pdo ->exec ('SET NAMES ' . $ pdo ->quote ($ config ['charset ' ]));
103- }
104-
105- return $ pdo ;
106- }
107-
10892 /**
10993 * 返回用于查询的PDO对象 (如果在事务中,将自动调用getPdo()以确保整个事务均使用主库)
11094 * @return PDO
@@ -144,11 +128,28 @@ public function getReadPdo()
144128 } while (count ($ slaveDbConfig ) > 0 );
145129
146130 // 从库不可用时使用主库
147- // return $this->readPdo = $this-> getPdo();
131+ // return $this->getPdo();
148132
149133 throw $ ex ;
150134 }
151135
136+ protected function makePdo (array $ config )
137+ {
138+ if (isset ($ config ['dsn ' ])) {
139+ $ dsn = $ config ['dsn ' ];
140+ } else {
141+ $ dsn = 'mysql:host= ' . $ config ['host ' ] . ';dbname= ' . $ config ['database ' ];
142+ }
143+
144+ $ pdo = new PDO ($ dsn , $ config ['username ' ], $ config ['password ' ], $ config ['options ' ]);
145+
146+ if (strpos ($ dsn , 'mysql: ' ) === 0 ) {
147+ $ pdo ->exec ('SET NAMES ' . $ pdo ->quote ($ config ['charset ' ]));
148+ }
149+
150+ return $ pdo ;
151+ }
152+
152153 /**
153154 * 返回表前缀
154155 * @return string
@@ -248,11 +249,20 @@ private function makeStatementAndExecute($connType, $sql, $params = array())
248249 try {
249250
250251 if ($ connType == self ::CONN_TYPE_READ ) {
251- $ statement = $ this ->getReadPdo ()-> prepare ( $ sql );
252+ $ pdo = $ this ->getReadPdo ();
252253 } else {
253- $ statement = $ this ->getPdo ()-> prepare ( $ sql );
254+ $ pdo = $ this ->getPdo ();
254255 }
256+
257+ //已连接上的服务器如果超时关闭连接后或者连接被手动kill,此方法并不会抛出PDOException,而是触发一条警告
258+ //Warning: PDO::prepare(): MySQL server has gone away
259+ //set global wait_timeout=5 连上mysql执行一条sql后,php中sleep(10),再执行下一条,就会报这个警告
260+ $ statement = @$ pdo ->prepare ($ sql );
261+
255262 $ start = microtime (true );
263+
264+ //如果执行时间较长的sql,被手动kill,则会在execute时先触发一条警告
265+ //Warning PDOStatement::execute(): MySQL server has gone away
256266 $ statement ->execute ($ params );
257267 $ this ->logQuery ($ sql , $ params , $ this ->getElapsedTime ($ start ));
258268 return $ statement ;
@@ -284,9 +294,11 @@ private function makeStatementAndExecute($connType, $sql, $params = array())
284294// $sql = $this->quoteSql($sql);
285295//
286296// if ($useReadPdo) {
287- // $statement = $this->getReadPdo()->prepare($sql);
297+ // $pdo = $this->getReadPdo();
298+ // $statement = @$pdo->prepare($sql);
288299// } else {
289- // $statement = $this->getPdo()->prepare($sql);
300+ // $pdo = $this->getPdo();
301+ // $statement = @$pdo->prepare($sql);
290302// }
291303//
292304// $start = microtime(true);
@@ -376,6 +388,12 @@ public function disconnect($connType = null)
376388 }
377389
378390 if ($ connType == self ::CONN_TYPE_READ ) {
391+
392+ //没有配置读库,只使用了主库
393+ if (!is_array ($ this ->config ['slave ' ]) || count ($ this ->config ['slave ' ]) == 0 ) {
394+ $ this ->pdo = null ;
395+ }
396+
379397 $ this ->readPdo = null ;
380398 return ;
381399 }
@@ -392,7 +410,10 @@ public function disconnect($connType = null)
392410 private function resolveDisconnect ($ connType , PDOException $ ex )
393411 {
394412 // https://dev.mysql.com/doc/refman/5.7/en/gone-away.html
395- if ($ this ->config ['serverGoneAwayReconnect ' ] && in_array ($ ex ->errorInfo [1 ], array (2006 , 2013 ))) {
413+ if ($ this ->config ['reconnect ' ]
414+ && $ this ->getTransactions () == 0
415+ && in_array ($ ex ->errorInfo [1 ], array (2006 , 2013 ))) {
416+
396417 $ this ->disconnect ($ connType );
397418 return ;
398419 }
@@ -401,7 +422,7 @@ private function resolveDisconnect($connType, PDOException $ex)
401422 }
402423
403424 /**
404- * 解析SQL中的占位置("?"或":"),主要用于调试SQL
425+ * 解析SQL中的占位置("?"或":") 用于调试SQL
405426 * @param string $sql
406427 * @param array $params
407428 * @return string
@@ -495,7 +516,7 @@ protected function quoteSimpleColumnName($name)
495516 }
496517
497518 /**
498- * 开启记录所有SQL, 如果不开启,默认只记录最后一次执行的SQL
519+ * 开启记录所有SQL, 如果不开启, 默认只记录最后一次执行的SQL
499520 */
500521 public function enableQueryLog ()
501522 {
@@ -526,13 +547,21 @@ protected function logQuery($sql, $params = array(), $time = null)
526547
527548 /**
528549 * 返回执行的SQL
550+ * @param bool $clear 是否清空
529551 * @return array
530552 */
531- public function getQueryLog ()
553+ public function getQueryLog ($ clear = true )
532554 {
533- return $ this ->queryLog ;
555+ $ data = $ this ->queryLog ;
556+
557+ if ($ clear ) {
558+ $ this ->queryLog = array ();
559+ }
560+
561+ return $ data ;
534562 }
535563
564+
536565 /**
537566 * 返回最近一次执行的sql语句
538567 * @return string
@@ -547,7 +576,7 @@ public function getLastSql()
547576 }
548577
549578 /**
550- * 计算所使用的时间
579+ * 计算所使用的时间 毫秒
551580 *
552581 * @param int $start
553582 * @return float
0 commit comments