PHP單例模式定義與使用實例詳解
本文實例講述了PHP單例模式定義與使用。分享給大家供大家參考,具體如下:
先簡單的介紹一下單例模式。單例模式就是在應用程序中保持某一個類實例只存在一個,而且不可以受外部環(huán)境的影響而生成這個類的第二個實例。它的優(yōu)點,實際點見,如果在WEB開發(fā)中,保持單一個數(shù)據(jù)操作類實例的存在,可以減少不必要的多余連接數(shù)據(jù)庫資源的消耗,對于大型的軟件開發(fā)來說,可以使用單例來維持程序的狀態(tài),使不同操作實現(xiàn)同步,因為單例一直占據(jù)內(nèi)存,而從不會有副本。
而對于PHP,使用單例最常用的場合莫過于寫一個數(shù)據(jù)庫操作類。不過在PHP中實現(xiàn)單例,有以下規(guī)則:
1)單例類必須擁有一個現(xiàn)式聲明的構(gòu)造函數(shù),并且是私有的。
2)單例類必須有一個靜態(tài)變量來存儲類的實例,這樣可以保持這個單例類就只有那么一個實例。
3)單例類必須提供一個靜態(tài)方法,供其他所有的對象應用這個單例。
為什么要滿足以上三個條件呢:
1)因為單例類在整個應用程序運行時,只能被創(chuàng)造一次,而且這種創(chuàng)造是不是通過外部調(diào)用而完成,而是自身完成。所以單例類是自己實例化自己,所以其構(gòu)造函數(shù)必須是私有。任何其他外部對象都不可以再次構(gòu)造一個單例類的副本。
2)因為單例類只能夠自己實例化自己,而又要為所有外部應用提供自己的實例,所以類內(nèi)部必須有一個可供外界訪問,而又是唯一不變的訪問存儲對象點,所以要提供一個靜態(tài)變量去存儲單例類自己實例化自己的那個實例對象。
3)因為單例類的構(gòu)造函數(shù)是私有的,所以單例類必須提供一個外部接口供外部環(huán)境調(diào)用單例類,所以必須有一個靜態(tài)方法,它可以初始化單例類或者返回單例類的對象的引用。
一個簡單的例子:
class DB{ private $_link; // 保持單例類的靜態(tài)變量 static $_instance; // 私有的構(gòu)造函數(shù) private function __construct(){ $this->_link = @mysqli_connect(__HOST__, __USER__, __PASSWORD__, __DATABASE__); if(! ($this->_link)){ echo 'Something wrong occurs on the database connection!'; } } // 防止單例類被克隆 private function __clone(){} // 外界訪問單例類實例的接口 public static function getInstance(){ if(! (self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } }
注意,以上定義的一個 __clone() 函數(shù),防止單例類對象被克隆。
以下也是一個簡單的數(shù)據(jù)庫操作類的單例,供參考:
class DB { /** * the database connection * @var resource * @access private */ private $_link; /** * the static instance of single db * @var object * @access static */ static $_instance; /** * construct the single object * @return null * @access private */ private function __construct(){ $this->_link = @mysqli_connect(__HOST__, __USER__, __PASSWORD__, __DATABASE__); if(! ($this->_link)){ echo 'Something wrong occurs on the database connection!'; } } /** * empty clone * @return null * @access private */ private function __clone(){} /** * for other object to get the instance of db * @return self::instance * @access public */ public static function getInstance(){ if(! (self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } /** * query * @param sql string * @param message string * @return resource * @access public */ public function query($sql,$message){ $result = @mysqli_query($this->$_link, $sql) or die($message . mysqli_error($this->$_link)); return $result; } /** * mysqli_num_rows * @param result resource * @return int * @access public */ public function num($result){ return @mysqli_num_rows($result); } /** * mysqli_fetch_array * @param result resource * @return array * @access public */ public function fetchArr($result){ return @mysqli_fetch_array($result); } /** * mysqli_insert_id * @return int * @access public */ public function last_id(){ return @mysqli_insert_id($this->_link); } /** * close the database connection * @param result resource * @return null * @access public */ public function close(){ @mysqli_close($this->_link); } /** * fetch once result from the specific sql query * @param sql string * @param message string * @return array * @access public */ public function fetchArrOnce($sql, $message){ $result = $this->query($sql, $message); $row = $this->fetchArr($result); return $row; } /** * fetch all results from the specific sql query * @param sql string * @param message string * @return array * @access public */ public function fetchArrMore($sql, $message){ $result = $this->query($sql, $message); $moreRow = array(); while($row = $this->fetchArr($result)){ $moreRow[] = $row; } return $moreRow; } /** * fetch the number of results from the specific sql query * @param sql string * @param message string * @return array * @access public */ public function fetchNum($sql, $message){ $result = $this->query($sql, $message); $resultNum = $this->num($result); return $resultNum; } /** * mysqli_prepare * @param sql string * @return stmt object * @access public */ public function prepare($sql){ return @mysqli_prepare($this->_link, $sql); } /** * mysqli_stmt_execute * @param stmt object * @param message string * @return bool * @access public */ public function stmt_execute($stmt, $message){ @mysqli_stmt_execute($stmt) or die($message . mysqli_error($this->_link)); } }
使用:
define("__HOST__", "localhost"); define("__USER__", "root"); define("__PASSWORD__", ""); define("__DATABASE__", "eee"); $db = DB::getInstance();
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O計入門教程》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結(jié)》、《PHP網(wǎng)絡編程技巧總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家PHP程序設計有所幫助。
- PHP實現(xiàn)單例模式最安全的做法
- php單例模式實現(xiàn)(對象只被創(chuàng)建一次)
- php利用單例模式實現(xiàn)日志處理類庫
- PHP最常用的2種設計模式工廠模式和單例模式介紹
- php設計模式 Singleton(單例模式)
- php單態(tài)設計模式(單例模式)實例
- php設計模式 Template (模板模式)
- PHP設計模式之觀察者模式(Observer)詳細介紹和代碼實例
- php設計模式 Proxy (代理模式)
- php設計模式 DAO(數(shù)據(jù)訪問對象模式)
- php設計模式小結(jié)
- php設計模式 Interpreter(解釋器模式)
- php設計模式 Facade(外觀模式)
- php設計模式 Strategy(策略模式)
- php設計模式 Adapter(適配器模式)
相關(guān)文章
將FCKeditor導入PHP+SMARTY的實現(xiàn)方法
這篇文章主要介紹了將FCKeditor導入PHP+SMARTY的實現(xiàn)方法,涉及整合FCKeditor與SMARTY的技巧,非常具有實用價值,需要的朋友可以參考下2015-01-01PHP查找數(shù)值數(shù)組中不重復最大和最小的10個數(shù)的方法
這篇文章主要介紹了PHP查找數(shù)值數(shù)組中不重復最大和最小的10個數(shù)的方法,涉及php中array_unique與array_slice方法的使用技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04PHP中一個有趣的preg_replace函數(shù)詳解
這篇文章主要給大家介紹了關(guān)于PHP中一個有趣的preg_replace函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用php具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-08-08PHP 開發(fā)環(huán)境配置(測試開發(fā)環(huán)境)
PHP發(fā)開環(huán)境配置(測試開發(fā)環(huán)境),測試環(huán)境是否配置的正確。2010-04-04php數(shù)據(jù)庫操作model類(使用__call方法)
這篇文章主要介紹了php數(shù)據(jù)庫操作model類,使用__call方法實現(xiàn)了數(shù)據(jù)的查詢功能,需要的朋友可以參考下2016-11-11PHP簡單數(shù)據(jù)庫操作類實例【支持增刪改查及鏈式操作】
這篇文章主要介紹了PHP簡單數(shù)據(jù)庫操作類實例,支持增刪改查及鏈式操作,非常適合小型項目的開發(fā)使用,末尾還提供了完整實例的下載地址,需要的朋友可以參考下2016-10-10php自定義函數(shù)實現(xiàn)JS的escape的方法示例
這篇文章主要介紹了php自定義函數(shù)實現(xiàn)JS的escape的方法,結(jié)合完整實例形式分析了php實現(xiàn)JS的escape功能函數(shù)的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-07-07PHP獲取數(shù)組中重復最多的元素的實現(xiàn)方法
這篇文章主要介紹了PHP獲取數(shù)組中重復最多的元素的實現(xiàn)方法,通過一個自定義函數(shù)遍歷數(shù)組實現(xiàn)這一功能,是非常使用的技巧,需要的朋友可以參考下2014-11-11