PHP 單例模式的解析和實戰

2021-03-02 PHP開發者

(給PHP開發者加星標,提升PHP技能)

轉自:Houzhyan

https://blog.csdn.net/h330531987/article/details/79100170

一、什麼是單例模式?

1、含義   

作為對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統全局地提供這個實例。它不會創建實例副本,而是會向單例類內部存儲的實例返回一個引用。

2、單例模式的三個要點:

(1). 需要一個保存類的唯一實例的靜態成員變量:

private static $_instance;

(2). 構造函數和克隆函數必須聲明為私有的,防止外部程序new類從而失去單例模式的意義:

private function __construct()   {       $this->_db = pg_connect('xxxx');  }   private function __clone()  {  }

(3). 必須提供一個訪問這個實例的公共的靜態方法(通常為getInstance方法),從而返回唯一實例的一個引用

public static function getInstance()    {        if(! (self::$_instance instanceof self) )       {            self::$_instance = new self();        }      return self::$_instance;      }

二、為什麼要使用單例模式?

1、PHP缺點:     

  

 PHP語言是一種解釋型的腳本語言,這種運行機制使得每個PHP頁面被解釋執行後,所有的相關資源都會被回收。也就是說,PHP在語言級別上沒有辦法讓某個對象常駐內存,這和asp.net、Java等編譯型是不同的,比如在Java中單例會一直存在於整個應用程式的生命周期裡,變量是跨頁面級的,真正可以做到這個實例在應用程式生命周期中的唯一性。然而在PHP中,所有的變量無論是全局變量還是類的靜態成員,都是頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個應用場景並需要共享同一對象資源時是非常有意義的。

2、單例模式在PHP中的應用場合:

(1)、應用程式與資料庫交互

一個應用中會存在大量的資料庫操作,比如過資料庫句柄來連接資料庫這一行為,使用單例模式可以避免大量的new操作,因為每一次new操作都會消耗內存資源和系統資源。

(2)、控制配置信息

 如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現.

三、如何實現單例模式?

1、普通的資料庫訪問例子:

<?php  .  $db = new DB(...);    $db->addUserInfo(...);    .    function getUserInfo()  {      $db = new DB(...);    $db = query(....);}  ?>  

2、應用單例模式對資料庫進行操作:

<?php    class DB    {        private $_db;        private static $_instance;            private function __construct(...)    {            $this->_db = pg_connect(...);    }            private function __clone() {};          public static function getInstance()    {            if(! (self::$_instance instanceof self) ) {                self::$_instance = new self();            }            return self::$_instance;        }            public function addUserInfo(...) {        }         public function getUserInfo(...)  {          } }  
$db = DB::getInstance(); $db->addUserInfo(...); $db->getUserInfo(...);
?>

3、深入理解

<?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(!empty($condition)){                            foreach($condition as $k=>$v){                  $where.=$k."='".$v."' and ";              }              $where='where '.$where .'1=1';          }          $fieldstr = '';          if(!empty($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(!empty($condition)){                            foreach($condition as $k=>$v){                  $where.=$k."='".$v."' and ";              }              $where='where '.$where .'1=1';          }          $updatastr = '';          if(!empty($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(!empty($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();  $db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));  echo $db->delete('demo',array('id'=>'2'));  db::getLastSql();  echo "<pre>";  ?>

- EOF -

看完本文有收穫?請分享給更多人

關注「PHP開發者」加星標,提升PHP技能


點讚和在看就是最大的支持❤️

相關焦點

  • a014.PHP實戰,單雙引號,區分單引號和雙引號
    關於單引號和雙引號,在以前的文章中,我是提到過的,這一期,我再來詳細的給大家說一說這個單雙引號,雖然很簡單,但很多人還是沒有能弄明白它們之間的區別在哪裡。代碼原型:<?php$a=1;echo "我是雙引號輸出的$a";echo 『我是單綽號輸出的$a』;?>代碼解析:首先定義一個變量a,並給它賦值為1,這個時候我們輸出變量a,分別以雙引號和單引號的形式進行輸出顯示。兩條代碼都是一樣的,只是一個在雙引號一個在單引號。
  • PHP八大設計模式
    設計模式單例模式解決的是如何在整個項目中創建唯一對象實例的問題,工廠模式解決的是如何不通過
  • Android設計模式(1)——單例模式
    單例模式使用的場景確保某個類有且只有一個對象的場景,避免產生多個對象消耗過多的資源,或者某種類型對象只應該有且只有一個,例如,創建一個對象需要消耗的資源過多,,如要訪問IO和資料庫等資源,這時就需要考慮使用單例模式。
  • 深入解析單例模式的七種實現
    來源:http://t.cn/E4J3ffX什麼是單例模式如何實現單例模式呢?單例模式的七種實現總結什麼是單例模式什麼是單例模式呢?我們引用一下維基百科:單例模式,也叫單子模式,是一種常用的軟體設計模式。在應用這個模式時,單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行為。
  • php解析json格式的文本
    昨天,在我校的高級培訓群裡,有同學諮詢了如何用php解析json格式的文本問題,老師發現這個問題比較典型,在此將相關的知識點總結分享給同學們,希望對其他同學掌握該知識點也能起到一些幫助。而且我們發現這是一個致命的錯誤,在foreach循環當中,無法將一個類的對象轉換為字符串輸出。
  • 大話設計模式之愛你一萬年:第二章 創建型模式:單例模式::我的女朋友只有你一個:3.4.5.單例模式的實現-餓漢/靜態/枚舉
    大話設計模式之愛你一萬年:第一章 設計模式基本概念:大話設計模式之愛你一萬年:第一章 設計模式基本概念:2.GoF的23種設計模式的分類和功能大話設計模式之愛你一萬年:第一章 設計模式基本概念:3.設計模式的六大原則大話設計模式之愛你一萬年:第二章 創建型模式:單例模式::我的女朋友只有你一個:1.單例模式的基本概念
  • 設計模式:單例模式
    基本概念1.1 原理單例模式可以說是所有設計模式中最簡單的一個了,這裡我們先直接給出它的概念然後再對它進行詳細的講解。單例模式就是:一個類只能有一個實例,並提供對該實例的全局訪問點。通俗地說,就是一個類只能創建一個對象,並且在程序的任何地方都能夠訪問到該對象。在某些情況下一些類只需要一個實例就夠了,我們以一個簡化的文件管理器作為例子來說明。
  • 手寫單例模式
    手寫單例模式為什麼要有單例模式: 在編程中,有些場景,是這樣的:
  • 單例模式襲來
    吹一波單例模式❝確保某個類只有一個實例,而且自行實例化並向整個系統提供整個實例。說白了,就是"獨苗"!什麼是"自行實例化"?就是整個實例是在類內部自己創建的,不是在別的類中創建的。❞單例誰都會寫,而且五花八門,且隨洒家來瞅瞅。
  • Python設計模式之單例模式
    什麼場景會用到單例模式呢?就是在系統工程中只想創建單個實例對象,比如資料庫連接池,Redis連接池,服務監控中心等。這個場景下,如果存在多個實例對象,那麼會有無法預測的異常。同時,在設計單例模式時,需要考慮的很重要的因素就是並發性,即多線程調用時是否會存在多個線程。那麼,如何設計使用單例模式呢?
  • 設計模式一:單例模式
    什麼是單例模式單例模式是指系統中的某個類只能有一個對象實例。
  • 深入淺出js單例模式
    何為單例模式?顧名思義,單例模式就是保證一個類僅有一個實例,也就是創建出來的兩個實例必須相等!
  • Java 實現單例模式的 9 種方法
    什麼是單例模式二. 單例模式的特點三. 單例模式VS靜態類四. 單例模式的實現一. 什麼是單例模式因進程需要,有時我們只需要某個類同時保留一個對象,不希望有更多對象,此時,我們則應考慮單例模式的設計。二. 單例模式的特點單例模式只能有一個實例。單例類必須創建自己的唯一實例。
  • Java的單例模式
    一、什麼是單例模式?
  • 全網最詳細的常見PHP漏洞全方面解析
    例 1://check_admin()用於檢查當前用戶權限,如果是 admin 設置$is_admin 變量為 true,然後下面判斷此變量是否為 true,然後執行管理的一些操作//ex1.php<?
  • Java單例模式深入詳解
    我主要是應用在使用普通類模擬枚舉類型裡,後來發現這就是傳說中的單例模式。構造函數弄成private 就是單例模式,即不想讓別人用new 方法來創建多個對象,可以在類裡面先生成一個對象,然後寫一個public static方法把這個對象return出去。
  • 為什麼要用單例模式?
    我們在編程中最常用的模式就是單例模式了,然而單例模式都用在什麼場合?為什麼不用靜態方法而要用單例模式呢?
  • 新手必須要懂的PHP學習路線以及10個PHP優化技巧
    adodb(資料庫接口)+javascript+xml+ajax(異步JavaScript和XML)+jquery(JS框架),熟悉OOP編程,學習thinkphp,zf框架,學習smarty模板引擎,pear (PHP擴展與應用庫),prototype(設計模式)。  對apache也應該買本管理員手冊好好看看。同時大致了解一下linux等等。
  • [理論+spss實戰]假設檢驗——單樣本t檢驗
    該值如何得出參考《[理論+SPSS實戰] 點估計與區間估計詳細解析》上邊的所有輸出數據我們在之前的推文裡都遇到過。唯獨有個數據沒見過:顯著性(雙尾)值為P=0.919。這個數據的出現為我們進行判斷接受或拒絕原假設提供了便利。
  • php項目實戰:代碼講解之上下架某條主題
    本節我們將重點介紹在php項目實戰中,如何上下架某條主題。需要注意的是,在完成這些代碼之前,我們需要先建立對應的資料庫,設置對應的伺服器,這部分內容在之前的資料庫內容一節中有介紹,如果有疑問的話可以留言討論。