PHP單例模式及應用場

PHP單例模式及應用場

設計模式?聽起來很高大上?的確是這樣的。設計模式就是組織代碼的方式,也就是說代碼不再是一條條的往下執行,按照前人總結的行之有效的方法,更有效的來組織代碼,這樣效率更高,而且看起來也清晰有序。

php單例模式,起初不是很熟悉,是在看MVC框架源代碼的時候才注意到的,設計模式在框架的設計應用中很廣泛,因此框架的代碼更有序高效。

單例模式顧名思義,就是隻有一個實例。作爲對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類我們稱爲單例類。

單例模式有三個特點:

1.某個類只能有一個實例。

2.這個類必須自己創建這個實例。

3.這個類必須自行向系統提供這個實例。

爲什幺使用"單例模式"?

先看一段代碼:(這是一個數據庫連接類)

複製代碼

<?php  
class Mysql  
{  
    // MYSQL數據庫連接信息  
    const HOSTNAME = "127.0.0.1";  
    const USERNAME = "root";  
    const PASSWORD = "***";  
    const DBNAME = "test";  
    const CHARSET = "utf8";  
 
    public function MysqlConnect()  
    {  
        $db = new mysqli(self::HOSTNAME, self::USERNAEM, self::PASSWORD, self::DBNAME); // 連接數據庫  
        $db->query("set names ".self::CHARSET);  
        if (mysqli_connect_errno())  
        {  
            throw new MysqlException("服務器系統故障", 1001);  
        }  
        else  
        {  
            return $db;  
        }  
    }  
}  
?>

複製代碼

每次數據庫連接都要new這個類,然後調用mysqlconnect方法,返回連接,然後close掉連接,頻繁的new和數據庫連接關閉操作非常的消耗資源!數據庫軟件系統中使用數據庫連接池,主要是節省打開或者關閉數據庫連接所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因爲何用單例模式來維護,就可以大大降低這種損耗。

因此,爲了避免資源消耗,我們有了下面的改進:

複製代碼

<?php
    class Mysql{
        //該屬性用來保存實例
        private static $conn;
        //構造函數爲private,防止創建對象
        private function __construct(){
            $this->conn = mysql_connect('localhost','root','');
        }
        //創建一個用來實例化對象的方法
        public static function getInstance(){
            if(!(self::$conn instanceof self)){
                self::$conn = new self;
            }
            return self::$conn;
        }
        //防止對象被複制
        public function __clone(){
            trigger_error('Clone is not allowed !');
        }
        
    }
    //只能這樣取得實例,不能new 和 clone
    $mysql = Mysql::getInstance();
?>

複製代碼

這樣就不用每次都來new這個類了,方便了很多。下面給一個詳細的:

複製代碼

<?php
class  Mysql
{
    private $DB;
    static private $_instance;
    // 連接數據庫
    private function __construct($host, $username, $password)
    {
        $this->DB = mysql_connect($host, $username, $password);
        $this->query("SET NAMES 'utf8'", $this->link);
        return $this->DB;
    }
    
    private function __clone(){}
    
    public static function getInstance($host, $username, $password)
    {    
        if( !(self::$_instance instanceof self) )
        {
            self::$_instance = new self($host, $username, $password);
        }
        return self::$_instance;
    }
    
    // 連接數據表
    public function select_db($database)
    {
        $this->result = mysql_select_db($database);
        return $this->result;
    }
    
    // 執行SQL語句
    public function query($query)
    {
        return $this->result = mysql_query($query, $this->link);
    }
    
    // 將結果集保存爲數組
    public function fetch_array($fetch_array)
    {
        return $this->result = mysql_fetch_array($fetch_array, MYSQL_ASSOC);
    }
    
    // 獲得記錄數目
    public function num_rows($query)
    {
        return $this->result = mysql_num_rows($query);
    }
    
    // 關閉數據庫連接
    public function close()
    {
        return $this->result = mysql_close($this->link);
    }
    
}
?>

複製代碼

使用的時候:

$con = Mysql::getInstance($host, $username, $password);
$con -> select_db($database);

 

當然,單例模式不僅僅只是應用在數據庫的操作類上面。還可以應用在這些方面:

1. 網站的計數器,一般也是採用單例模式實現,否則難以同步。

2. 應用程序的日誌應用,一般都何用單例模式實現,這一般是由於共享的日誌文件一直處於打開狀態,因爲只能有一個實例去操作,否則內容不好追加。

3. Web應用的配置對象的讀取,一般也應用單例模式,這個是由於配置文件是共享的資源。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章