之前在《【PHP】利用php的構造函數與析構函數編寫MySQL數據庫查詢類》(點擊打開鏈接)寫過的Mysql數據庫查詢類還不夠完美,利用《【Java】單例模式》(點擊打開鏈接)介紹的思想可以將這個數據庫鏈接類搞成單例,不會因為多個用戶訪問網站就創建一個數據庫查詢實例,拖慢整個網站的速度,讓網站的數據庫壓力比較大,造成網站的速度下降得很厲害。
單例實現最關鍵的,還是那3點:
1、私有構造函數,這里無須像Java那樣私有無參數的構造函數,php不允許有多個構造函數——即使這些構造函數參數不同也不可以。
2、私有克隆類的函數
3、暴露一個公有的“創造實例函數”供調用,這個“創造實例函數”判斷如果已存在相應實例,返回此實例,沒有才創建。
這樣保證此數據庫連接類有且只有一個。
直接用一個例子說明,數據庫test中有表user
先利用利用單例模式設計數據庫連接Model類,將這張表的內容查詢到網頁上:
具體代碼如下:
- <?php
- class db{
- private $link;
- //db類單例開始
- //保存類實例的私有靜態成員變量
- private static $_instance;
- //定義一個私有的構造函數,確保單例類不能通過new關鍵字實例化,只能被其自身實例化
- private function __construct($host,$username,$password,$database){
- $this->link=mysql_connect($host,$username,$password);
- if(!$this->link){
- die("連接失敗!");
- }
- mysql_query("set names utf8;");
- mysql_select_db($database);
- }
- //定義私有的__clone()方法,確保單例類不能被復制或克隆
- private function __clone(){}
- public static function getInstance($host, $username, $password,$database) {
- //檢測類是否被實例化
- if(!(self::$_instance instanceof self)){
- self::$_instance=new db($host,$username,$password,$database);
- }
- return self::$_instance;
- }
- //執行SQL語句
- public function query($query){
- return mysql_query($query, $this->link);
- }
- //關閉數據庫連接
- public function close(){
- return mysql_close($this->link);
- }
- }
- //調用單例類測試部分
- header("Content-type: text/html; charset=utf-8"); //設置網頁編碼
- $dbconnector=db::getInstance("localhost","root","root","test");//創建數據庫連接類
- $result=$dbconnector->query("select * from user");//查詢數據庫
- for($i=0;$row=mysql_fetch_array($result);$i++){//打印查詢結果
- echo $row['id'].",".$row['username'].",".$row['password']."<br/>";
- }
- ?>
這樣保證了class db所對應的實例$dbconnector有且只有一個,再有一句:
- $dbconnector1=db::getInstance("localhost","root","root","test");//創建數據庫連接類
還是會返回原來的已經創建實例$dbconnector,更應該說操作$dbconnector與$dbconnector1是同樣的效果,它們就是同一個東西,不會在服務器的內存上多開辟資源來存放$dbconnector與$dbconnector1,因為db被單例了,從而達到減少數據庫壓力的目的。