❶ php單例模式應用場景有哪些
單例模式的要點有三個:
一是某個類只能有一個實例;
二是它必須自行創建這個實例;
三是它必須自行向整個系統提供這個實例。
復制代碼 代碼如下:
<?php
/* 單例模式舉例,其要點如下:
*
* 1. $_instance 必須聲明為靜態的私有變數
* 2. 構造函數和克隆函數必須聲明為私有的,這是為了防止外部程序 new 類從而失去單例模式的意義
* 3. getInstance()方法必須聲明為公有的,必須調用此方法以返回唯一實例的一個引用
* 4. ::操作符只能訪問靜態變數或靜態函數
* 5. PHP的單例模式是相對而言的,因為PHP的解釋運行機制使得每個PHP頁面被解釋執行後,所有的相關資源都會被回收。
* 也就是說,PHP在語言級別上沒有辦法讓某個對象常駐內存。在PHP中,所有的變數都是頁面級的,無論是全局變數,
* 還是類的靜態成員,都會在頁面執行完畢後被清空,結果會重新建立新的對象,這樣也就完全失去了Singleton的意義。
* 不過,在實際應用中同一個頁面中可能會存在多個業務邏輯,這時單例模式就起到了很重要的作用,有效的避免了重復
* new 對象(注: new 對象會消耗內存資源)這么一個行為,所以我們說PHP的單例模式是相對而言的
*
*/
class People
{
static private $_instance = NULL;
public $height = '';
public $age = '';
private function __construct()
{
$this->height = '185';
$this->age = 25;
}
private function __clone()
{
//do something
}
static public function getInstance()
{
if(!self::$_instance instanceof self)
{
//echo 'lgh-big';
self::$_instance = new self;
}
else
{
//for testing only
//echo 'gdc-xiaoairener';
}
return self::$_instance;
}
public function getHeight()
{
echo $this->height;
}
public function getAge()
{
echo $this->age;
}
}
function testInstance()
{
People::getInstance()->getAge();
}
//begin to use the class
$lgh = People::getInstance();
$lgh->getHeight();
echo '<br />';
testInstance();
?>
優點:單例模式可以避免大量的new操作,因為每一次new操作都會消耗內存資源和系統資源
缺點:在PHP中,所有的變數無論是全局變數還是類的靜態成員,都是 頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只 是針對單次頁面級請求時出現多個應用場景並需要共享同一對象資源時是非常有意義的。
Why–為什麼要使用PHP單例模式?
PHP的一個主要應用場合就是應用程序與資料庫打交道的應用場景,所以一個應用中會存在大量的資料庫操作,比如過資料庫句柄來連接資料庫這一行為,使用單例模式可以避免大量的new操作,因為每一次new操作都會消耗內存資源和系統資源。
還是有些抽象,給出代碼片段。
使用傳統方式編碼
復制代碼 代碼如下:
<?php
......
//初始化一個資料庫句柄
$db = new DB(...);
//比如有個應用場景是添加一條用戶信息:
$db->addUserInfo();
......
//然而我們在另外一個地方可能要查找用戶的信息,這個情景出現在一個函數中,這時要用到資料庫句柄資源,我們可能需要這么去做
......
function test(){
......
//這時我們不得不重新初始化一個資料庫句柄,試想多個應用場景下,這樣的代碼是多麼可怕啊?!
$db = new DB(...);
$db->getUserInfo();
......
//有些朋友或許會說,我也可以不這樣做啊,我直接利用global關鍵字不就可以了嗎?的確,global可以解決問題,也起到了單例模式的作用,但是OOP中,我們拒絕這樣來編寫代碼,因為global存在安全隱患,請參考相關書籍,同時單例模式恰恰是對全局變數的一種改進,避免了那些存儲唯一實例的全局變數污染命名空間
global $db; //OOP中,我們不提倡這樣編寫代碼
......
}
使用單例模式編碼
復制代碼 代碼如下:
<?php
......
//所有的應用情景只有一個資料庫句柄資源,嘿嘿,效率老高了,
//資源也大大的得到節省,代碼簡潔明了:)
DB::getInstance()->addUserInfo();
DB::getInstance()->getUserInfo();
......
How–如何來編寫PHP單例模式?
在了解了單例模式的應用場景之後,下面我們通過編寫單例模式的具體實現代碼來掌握PHP單例模式的核心要點,代碼如下:
復制代碼 代碼如下:
<?php
/**
* PHP單例模式演示舉例
* @author guohua.li
* @modify 2010-07-11
* @website http://blog.163.com/lgh_2002/
*/
class User{
/**
* 靜態成品變數 保存全局實例
* @access private
*/
static private $_instance = NULL;
/**
* 私有化構造函數,防止外界實例化對象
*/
private function __construct() {}
/**
* 私有化克隆函數,防止外界克隆對象
*/
private function __clone(){}
/**
* 靜態方法, 單例統一訪問入口
* @return object 返回對象的唯一實例
*/
static public function getInstance() {
if (is_null(self::$_instance) || !isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* 測試方法: 獲取用戶名字
*/
public function getName() {
echo 'hello liguohua!';
}
}
從以上代碼中,我們總結出PHP單例模式實現的核心要點有如下三條:
1.需要一個保存類的唯一實例的靜態成員變數(通常為$_instance私有變數)
2.構造函數和克隆函數必須聲明為私有的,這是為了防止外部程序new類從而失去單例模式的意義
3.必須提供一個訪問這個實例的公共的靜態方法(通常為getInstance方法),從而返回唯一實例的一個引用
PHP單例模式的缺點
眾所周知,PHP語言是一種解釋型的腳本語言,這種運行機制使得每個PHP頁面被解釋執行後,所有的相關資源都會被回收。也就是說,PHP在語言級別上沒有辦法讓某個對象常駐內存,這和asp.net、Java等編譯型是不同的,比如在Java中單例會一直存在於整個應用程序的生命周期里,變數是跨頁面級的,真正可以做到這個實例在應用程序生命周期中的唯一性。然而在PHP中,所有的變數無論是全局變數還是類的靜態成員,都是頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個應用場景並需要共享同一對象資源時是非常有意義的。
❷ PHP中幾種常見的開發模式
單例模式
$_instance必須聲明為靜態的私有變數
構造函數和析構函數必須聲明為私有,防止外部程序new 類從而失去單例模式的意義
getInstance()方法必須設置為公有的,必須調用此方法 以返回實例的一個引用
::操作符只能訪問靜態變數和靜態函數
new對象都會消耗內存
使用場景:最常用的地方是資料庫連接。
使用單例模式生成一個對象後, 該對象可以被其它眾多對象所使用。
私有的__clone()方法防止克隆對象
單例模式,使某個類的對象僅允許創建一個。構造函數private修飾,
申明一個static getInstance方法,在該方法里創建該對象的實例。如果該實例已經存在,則不創建。比如只需要創建一個資料庫連接。
工廠模式
工廠模式,工廠方法或者類生成對象,而不是在代碼中直接new。
使用工廠模式,可以避免當改變某個類的名字或者方法之後,在調用這個類的所有的代碼中都修改它的名字或者參數。
注冊模式
注冊模式,解決全局共享和交換對象。已經創建好的對象,掛在到某個全局可以使用的數組上,在需要使用的時候,直接從該數組上獲取即可。將對象注冊到全局的樹上。任何地方直接去訪問。
策略模式
策略模式,將一組特定的行為和演算法封裝成類,以適應某些特定的上下文環境。
eg:假如有一個電商網站系統,針對男性女性用戶要各自跳轉到不同的商品類目,並且所有的廣告位展示不同的廣告。在傳統的代碼中,都是在系統中加入各種if else的判斷,硬編碼的方式。如果有一天增加了一種用戶,就需要改寫代碼。使用策略模式,如果新增加一種用戶類型,只需要增加一種策略就可以。其他所有的地方只需要使用不同的策略就可以。
首先聲明策略的介面文件,約定了策略的包含的行為。然後,定義各個具體的策略實現類。
執行結果圖:
總結:
通過以上方式,可以發現,在不同用戶登錄時顯示不同的內容,但是解決了在顯示時的硬編碼的問題。如果要增加一種策略,只需要增加一種策略實現類,然後在入口文件中執行判斷,傳入這個類即可。實現了解耦。
實現依賴倒置和控制反轉(有待理解)
通過介面的方式,使得類和類之間不直接依賴。在使用該類的時候,才動態的傳入該介面的一個實現類。如果要替換某個類,只需要提供一個實現了該介面的實現類,通過修改一行代碼即可完成替換。
觀察者模式
1:觀察者模式(Observer),當一個對象狀態發生變化時,依賴它的對象全部會收到通知,並自動更新。
2:場景:一個事件發生後,要執行一連串更新操作。傳統的編程方式,就是在事件的代碼之後直接加入處理的邏輯。當更新的邏輯增多之後,代碼會變得難以維護。這種方式是耦合的,侵入式的,增加新的邏輯需要修改事件的主體代碼。
3:觀察者模式實現了低耦合,非侵入式的通知與更新機制。
定義一個事件觸發抽象類。
當某個事件發生後,需要執行的邏輯增多時,可以以松耦合的方式去增刪邏輯。也就是代碼中的紅色部分,只需要定義一個實現了觀察者介面的類,實現復雜的邏輯,然後在紅色的部分加上一行代碼即可。這樣實現了低耦合。
裝飾器模式
1:裝飾器模式,可以動態的添加修改類的功能
2:一個類提供了一項功能,如果要在修改並添加額外的功能,傳統的編程模式,需要寫一個子類繼承它,並重寫實現類的方法
3:使用裝飾器模式,僅需要在運行時添加一個裝飾器對象即可實現,可以實現最大額靈活性。
❸ php設計模式之單例、多例設計模式的應用分析
本篇文章是對php設計模式中的單例與多例設計模式的應用進行了詳細的分析介紹 需要的朋友參考下單例(Singleton)模式和不常銷灶見的多例(Multiton)模式控制著應用程序中類的數量 如模式名稱 單例只能實例化一次 只有一個對象 多例模式可以多次實例化 基於Singleton的特性 我們經常用Singleton配置應用程序並定義應用程序中可能隨時訪問的變數 但有時並不推薦使用Singleton 因為它生成了一個全局狀態且 該單一根對象沒有封裝任何系統功能 多數情況下 會使單元明斗歲測試和調試變得困難 讀者根據情況自行決定 代碼示例
復制代碼 代碼如下: <?php class SingletonExample{ private function __construct(){}//防止直接實例化 public static function getInstance(){ //不與任何對象有關聯 static $instance=null; //調用此函數的所有代碼共享該變數 不必要讓其是類的靜態變數 if($instance==null){ $instance=new SingletonExample(); } return $instance; } } $obj =SingletonExample::getInstance(); $obj =SingletonExample::getInstance(); var_mp($obj ===$obj );// true 是同一個實例 ?>Multiton與singleton相似 不同的是後者需要getInstance()函數傳遞關鍵值 對於給定的關鍵值只會存在唯一的對象實例激睜 如果有多個節點 每個節點擁有唯一的表識符 且各個節點在某單次執行(如cms里的節點)可能出現多次 那麼就可以用Multiton模式實現這些節點啊 Multiton節省內存 並確保同一個對象的多個實例不發生沖突 示例
復制代碼 代碼如下: lishixin/Article/program/PHP/201311/21166
❹ 為什麼要使用PHP單例模式及應用實例
單例模式顧名思義,就是只有一個實例。作為對象的創建模式,
單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類我們稱之為單例類。單例模式的要點有三個:一是某個類只能有一個實例;二是它必須自行創建這個實例;三是它必須自行向整個系統提供這個實例。下面我們討論下為什麼要使用PHP單例模式?多數人都是從單例模式的字面上的意思來理解它的用途,
認為這是對系統資源的節省,
可以避免重復實例化,
是一種"計劃生育".
而PHP每次執行完頁面都是會從內存中清理掉所有的資源.
因而PHP中的單例實際每次運行都是需要重新實例化的,
這樣就失去了單例重復實例化的意義了.
單單從這個方面來說,
PHP的單例的確有點讓各位失望.
但是單例僅僅只有這個功能和應用嗎?
答案是否定的,我們一起來看看。1.
php的應用主要在於資料庫應用,
所以一個應用中會存在大量的資料庫操作,
在使用面向對象的方式開發時(廢話),
如果使用單例模式,
則可以避免大量的new
操作消耗的資源。2.
如果系統中需要有一個類來全局控制某些配置信息,
那麼使用單例模式可以很方便的實現.
這個可以參看zend
Framework的FrontController部分。
❺ php 單例模式
單例模式是一種常用的軟體設計模式,可以保證系統中一個類只有一個實例,從而達到節約系統資源提升特殊類使用效率的目的
php實現單例模式的方法
classA{
//靜態屬性
privatestatic$_instance;
//空的克隆方法,防止被克隆
privatefunction__clone(){}
//獲取實例
(){
if(!(self::$_instanceinstanceofself)){
self::$_instance=newA();
}
returnself::$_instance;
}
}
//調用
$obj=A::getInstance();