PHP 數據庫鏈接池實現(轉)

 


此文着實無聊,不要浪費時間往下看啦 
java

摘要

以前老是以腳本面向過程的方式寫PHP代碼,因此很大程度上來講,既不規範,也不安全,更不容易維護。爲了代碼的重用,準備寫一套本身的工具庫,這樣的話,之後寫項目的時候就能夠很輕鬆的進行使用啦。mysql

今天要進行實現的是一個數據庫鏈接池,以配置文件的方式來實現。sql

xml

XML做爲一門高可用的結構化語言,做爲配置文件真的是言簡意賅,雖然相比於近來配置文件界的YAML, JSON等翹楚來講,可能有效數據的佔比比較小,可是這種冗餘是有其存在的價值的。數據庫

基本上,看完xml的節點就能夠知道其功能。這也是爲何大項目都會使用XML做爲配置文件的緣由。數組

能夠容忍冗餘,可是不能帶來一點歧義,或者維護困難方面的問題。瀏覽器

在PHP中,使用XML文件會是一件賞心悅目的事情,雖然相對於Java程序而言,如此。可是相比於Python處理,PHP程序就顯得沒有那麼優雅了。安全

讀取配置文件

讀取配置文件其實說白了就是對文件的讀取,而後包裝一下。我經常使用的有以下兩種方式。bash

簡易方式

第一次使用這個簡易方式的時候,真的是有點鬱悶。函數

$content = file_get_contents("filename.xml"); echo $content;
  • 1
  • 2

結果使用瀏覽器訪問這個測試用的php文件時,卻只顯示了xml的內容部分,可是節點信息什麼的根本沒有顯示。

而後我還特意查閱了一下幫助文檔,這個函數返回的結果是字符串無疑的啊。而後vardump以後也證實了這一點。因而也沒有多想,還覺得這種方式能自動的過濾掉XML的標籤TAG信息呢。

最後一個偶然的測試,打開了網頁源代碼,發現這個函數確實讀到了XML的全部信息,只不過顯示在瀏覽器上就會被瀏覽器給自動解析了。因此只能看到相關的內容部分。

常規方式

常規方式就是循序漸進的讀取文件了。其他的話和上述方案一致。

// 讀取配置文件內容 $handle = fopen("filepath", "r"); $content = fread($handle, filesize("filepath"));
  • 1
  • 2
  • 3

PHP解析XML

上述兩種讀取文件,其實都是爲了PHP解析XML來作準備的。關於PHP解析XML的方式的博客有不少。方式也有不少,像simplexml,XMLReader,DOM啦等等。可是對於比較小型的xml配置文件,simplexml就足夠了。

配置文件

<?xml version="1.0" encoding="UTF-8" ?> <mysql> <!-- 爲防止出現意外,請按照此標準順序書寫.其實也無所謂了 --> <host>localhost</host> <user>root</user> <password>123456</password> <db>test</db> <port>3306</port> </mysql> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

解析

<?php /** * 做爲解析XML配置文件必備工具 */ class XMLUtil { public static $dbconfigpath = "./db.config.xml"; public static function getDBConfiguration() { $dbconfig = array (); try { // 讀取配置文件內容 $handle = fopen(self::$dbconfigpath, "r"); $content = fread($handle, filesize(self::$dbconfigpath)); // 獲取xml文檔根節點,進而獲取相關的數據庫信息 $mysql = simplexml_load_string($content); // 將獲取到的xml節點信息賦值給關聯數組,方便接下來的方法調用 $dbconfig['host'] = $mysql->host; $dbconfig['user'] = $mysql->user; $dbconfig['password'] = $mysql->password; $dbconfig['db'] = $mysql->db; $dbconfig['port'] = $mysql->port; // 將配置信息以關聯數組的形式返回 return $dbconfig; } catch ( Exception $e ) { throw new RuntimeException ( "<mark>讀取數據庫配置文件信息出錯!</mark><br />" ); } return $dbconfig; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

數據庫鏈接池

對於PHP程序而言,優化永無止境。而數據庫鏈接池就在必定程度上起到了優化的做用。其使得對用戶的每個請求而言,無需每次都像數據庫申請連接資源。而是經過已存在的數據庫鏈接池中的連接來返回,從時間上,效率上,都是一個大大的提高。

因而,這裏簡單的模擬了一下數據庫鏈接池的實現。核心在於維護一個「池」。

從池子中取,用畢,歸還給池子。

<?php
/**x * PHP中的數據庫 工具類設計 * 郭璞 * 2016年12月23日 * **/ class DbHelper { private $dbconfig; private $dbpool; public $poolsize; public function __construct($poolsize = 20) { if (! file_exists ( "./utils.php" )) { throw new RuntimeException ( "<mark>utils.php文件丟失,沒法進行配置文件的初始化操做!</mark><br />" ); }else { require './utils.php'; } // 初始化 配置文件信息 $this->dbconfig = XMLUtil::getDBConfiguration (); // 準備好數據庫鏈接池「僞隊列」 $this->poolsize = $poolsize; $this->dbpool = array (); for($index = 1; $index <= $this->poolsize; $index ++) { $conn = mysqli_connect ( $this->dbconfig ['host'], $this->dbconfig ['user'], $this->dbconfig ['password'], $this->dbconfig ['db'] ) or die ( "<mark>鏈接數據庫失敗!</mark><br />" ); array_push ( $this->dbpool, $conn ); } } /** * 從數據庫鏈接池中獲取一個數據庫連接資源 * * @throws ErrorException * @return mixed */ public function getConn() { if (count ( $this->dbpool ) <= 0) { throw new ErrorException ( "<mark>數據庫鏈接池中已無連接資源,請稍後重試!</mark>" ); } else { return array_pop ( $this->dbpool ); } } /** * 將用完的數據庫連接資源放回到數據庫鏈接池 * * @param unknown $conn * @throws ErrorException */ public function release($conn) { if (count ( $this->dbpool ) >= $this->poolsize) { throw new ErrorException ( "<mark>數據庫鏈接池已滿</mark><br />" ); } else { array_push ( $this->dbpool, $conn ); } } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

測試

申請過多時,拒絕請求

在申請數據庫鏈接小於20的時候,程序直接從數據庫鏈接池中獲取。

正常請求,正常獲取

當申請的數據庫連接資源大於數據庫鏈接池的上限時,不予提供。並提示異常。

數據庫鏈接池中無鏈接轉時提示異常

已滿後拒絕放入

當數據庫鏈接池內已滿的時候,若是想回首自定義的數據庫連接資源,則不予支持,並報錯提示。 
已滿後拒絕放入

總結

回顧一下,本次試驗主要是以面向對象的角度,設計並實現了一個簡易的數據庫鏈接池。在必定程度上對PHP代碼的優化起到了做用。

另外簡單的使用了simplexml對於XML文件的解析處理, 以及經常使用的對於文件讀取的操做。

相關文章
相關標籤/搜索