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應用的配置對象的讀取,一般也應用單例模式,這個是由於配置文件是共享的資源。