單例模式是php中一個為了簡化大家開發及重復調用的一個功能,下面我來給各位朋友詳細介紹單例模式用法。
1.單例模式的概念
顧名思義,單例模式只有一個實例,而且自行實例化,向全局提供這個實例,需要強調的是,單例模式,確保某個類只能有一個實例!
2.單例模式的三個要點
(1)需要一個靜態變量來保存類的唯一實例,代碼如下:
private static $_instance;
(2)構造函數和克隆函數必須為私有的,防止用戶創建對象和復制實例對象,代碼如下:
- private function __construct()
- {
- //私有化默認構造方法,防止外界直接實例化
- }
- private function __clone()
- {
- //私有化克隆方法,防止用戶復制實例
- }
(3)必須提供一個公共的靜態方法(一般為getInstance),從而返回一個唯一實例的引用,實例代碼如下:
- public static function getInstance()
- {
- if(! (self::$_instance instanceof self) )
- {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
3.php中使用單例模式的原因
PHP語言是一種解釋型的腳本語言,這種運行機制使得每個PHP頁面被解釋執行后,所有的相關資源都會被回收,也就是說,PHP在語言級別上沒有辦法讓某個對象常駐內存,這和asp.net、Java等編譯型是不同的,比如在Java中單例會一直存在于整個應用程序的生命周期里,變量是跨頁面級的,真正可以做到這個實例在應用程序生命周期中的唯一性。然而在PHP中,所有的變量無論是全局變量還是類的靜態成員,都是頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢后被清空,這樣似乎PHP單例模式就沒有什么意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個應用場景并需要共享同一對象資源時是非常有意義的。
4.如何實現單例模式,代碼如下:
- <?php
- /**
- * 單例模式示例:Demo
- */
- class Demo{
- //靜態成員變量,用來保存全局實例
- private static $_instance;
- //私有化構造方法,保證外界不能直接實例化
- private function __construct(){
- }
- //私有化克隆方法,防止用戶復制實例
- private function __clone(){
- }
- //返還此類的唯一實例
- public function getInstance(){
- if(!(self::$_instance instanceof self))
- {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- //這是第一個測試方法
- public function test1Function(){
- echo '這是第一個測試方法';
- }
- //這是第二個測試方法
- public function test2Function(){
- echo '這是第二個測試方法';
- }
- }
- //正確的使用方法
- @$demo = Demo::getInstance();
- $demo->test1Function();
- $demo->test2Function();
- //這樣實例化會出錯,因為構造方法為private
- //$demo_new = new Demo;
- //復制demo會出錯,因為默認的clone方法為private
- // $demo_clone = clone $demo;
- ?>
5.單利模式的應用場合
(1)應用與數據庫的交互,多用于數據庫的連接
1、普通的數據庫訪問例子,代碼如下:
- <?php
- ......
- //初始化一個數據庫句柄
- $db = new DB(...);
- //添加用戶信息
- $db->addUserInfo(...);
- ......
- //在函數中訪問數據庫,查找用戶信息
- function getUserInfo()
- {
- $db = new DB(...);//再次new 數據庫類,和數據庫建立連接
- $db = query(....);//根據查詢語句訪問數據庫
- }
- ?>
2、應用單例模式對數據庫進行操作,實例代碼如下:
- <?php
- class DB
- {
- private $_db;
- private static $_instance;
- private function __construct(...)
- {
- $this->_db = pg_connect(...);//postgrsql
- }
- private function __clone() {}; //覆蓋__clone()方法,禁止克隆
- public static function getInstance()
- {
- if(! (self::$_instance instanceof self) ) {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- public function addUserInfo(...)
- {
- }
- public function getUserInfo(...)
- {
- }
- }
- //test
- $db = DB::getInstance();
- $db->addUserInfo(...);
- $db->getUserInfo(...);
- ?>
深入理解,實例代碼如下:
- <?php
- class db {
- public $conn;
- public static $sql;
- public static $instance=null;
- private function __construct(){
- require_once('db.config.php');
- $this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
- if(!mysql_select_db($db['database'],$this->conn)){
- echo "失敗";
- };
- mysql_query('set names utf8',$this->conn);
- }
- public static function getInstance(){
- if(is_null(self::$instance)){
- self::$instance = new db;
- }
- return self::$instance;
- }
- /**
- * 查詢數據庫
- */
- public function select($table,$condition=array(),$field = array()){
- $where='';
- if(!emptyempty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- $fieldstr = '';
- if(!emptyempty($field)){
- foreach($field as $k=>$v){
- $fieldstr.= $v.',';
- }
- $fieldstr = rtrim($fieldstr,',');
- }else{
- $fieldstr = '*';
- }
- self::$sql = "select {$fieldstr} from {$table} {$where}";
- $result=mysql_query(self::$sql,$this->conn);
- $resuleRow = array();
- $i = 0;
- while($row=mysql_fetch_assoc($result)){
- foreach($row as $k=>$v){
- $resuleRow[$i][$k] = $v;
- }
- $i++;
- }
- return $resuleRow;
- }
- /**
- * 添加一條記錄
- */
- public function insert($table,$data){
- $values = '';
- $datas = '';
- foreach($data as $k=>$v){
- $values.=$k.',';
- $datas.="'$v'".',';
- }
- $values = rtrim($values,',');
- $datas = rtrim($datas,',');
- self::$sql = "INSERT INTO {$table} ({$values}) VALUES ({$datas})";
- if(mysql_query(self::$sql)){
- return mysql_insert_id();
- }else{
- return false;
- };
- }
- /**
- * 修改一條記錄
- */
- public function update($table,$data,$condition=array()){
- $where='';
- if(!emptyempty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- $updatastr = '';
- if(!emptyempty($data)){
- foreach($data as $k=>$v){
- $updatastr.= $k."='".$v."',";
- }
- $updatastr = 'set '.rtrim($updatastr,',');
- }
- self::$sql = "update {$table} {$updatastr} {$where}";
- return mysql_query(self::$sql);
- }
- /**
- * 刪除記錄
- */
- public function delete($table,$condition){
- $where='';
- if(!emptyempty($condition)){
- foreach($condition as $k=>$v){
- $where.=$k."='".$v."' and ";
- }
- $where='where '.$where .'1=1';
- }
- self::$sql = "delete from {$table} {$where}";
- return mysql_query(self::$sql);
- }
- public static function getLastSql(){
- echo self::$sql;
- }
- }
- $db = db::getInstance();
- //$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array
- ('name','password'));
- //echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
- //echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
- echo $db->delete('demo',array('id'=>'2'));
- db::getLastSql();
- echo "<pre>";
- ?>
php中有很多的設計模式,其中的單例模式是我們寫代碼的時候較為常用的一種模式,它不但能夠有效的減少new操作的資源消耗.而且能夠很方便的對某些全局配置信息進行控制!希望大家在php學習中深刻理解單例模式的應用。
新聞熱點
疑難解答