PHP一例モード応用例【複数の接続データベースは一度だけ実例化する】


本論文の例はPHPの単一例のモード応用について述べる。皆さんに参考にしてあげます。具体的には以下の通りです。
以前は仕事を始めたばかりの頃はよくデータベースに接続していましたが、データベースを使うたびにnewで実例を挙げて接続していました。データベースに接続する回数があまり頻繁ではなかったので、大丈夫です。その后、担当者から言われました。今のように毎回データベースに接続しています。データの読み取りが頻繁であれば、データベースとシステムにもたらす圧力が大きいと思います。何とかデータベースに接続して、再度使う時はnewを使わないでください。その時は主管が私を単一の例のモードで案内してくれました。開発モードが分かりませんでした。はい、無駄話はやめて、次は単例モードを見にきます。
単例モード(職責モード):
簡単に言えば、一つの対象(設計モードを学ぶ前に、対象に向かう思想を比較的に理解する必要がある)は一つの特定の任務だけを担当します。
単例クラス:
1、コンストラクタはprivateと表記する必要があります。(アクセス制御:外部コードがnewオペレータを使用してオブジェクトを作成するのを防止します。)単一の例類は他のクラスでは実装できません。自分自身のインスタンス化しかできません。
2、保存クラスのインスタンスを持つスタティックメンバー変数
3、この例にアクセスするための共通の静的方法(一般的にはgetInstance()方法で実施される例示的なクラスであり、instanceofオペレータによってクラスがすでに実装されているかどうかを検出することができる)を有する。
また、__clone()を作成する必要があります。オブジェクトの複製(クローン)を防ぐ方法があります。
なぜPHPシングルモデルを使うのですか?
1、phpのアプリケーションは主にデータベースアプリケーションにあり、一つのアプリケーションには大量のデータベース操作が存在し、一例モードを使用すると、大量のnewの操作で消費されるリソースを回避することができる。
2、システムの中にいくつかの構成情報を大域的に制御するクラスが必要であれば、単一の例のモードを使って簡単に実現できます。これはZFのFrontController部分を参照することができます。
3、一回のページ要求において、調整が容易である。すべてのコード(例えば、データベース操作クラスdb)が一つのクラスに集中しているため、クラスにフックを設置し、ログを出力することができ、これにより、var_dumpechoを回避することができる。
コード(公式文書)

<?php
class Singletons{
  //           
  private static $instance;
  //        private,        
  private function __construct()
  {
    echo 'Iam constructed';
  }
  // singleton   
  public static function singleton()
  {
    if (!isset(self::$instance)) {
      $c = __CLASS__;
      self::$instance =new$c;
    }
    return self::$instance;
  }
  // Example       
  public function bark()
  {
    echo 'Woof!';
  }
  //           
  public function __clone()
  {
    trigger_error('Clone is not allowed.',E_USER_ERROR);
  }
}//endclass singletons
  //       ,          private
  //$test= new Singletons();
  //      Example      
  $test= Singletons::singleton();
  $test->bark();
  //          E_USER_ERROR.
  $test_clone= clone $test;
?>

結果:
I am constructed   ファイアー
Fatal error:
Cloone is not allowed.in E:\APMServ 5.2.6\www\httdocs\Lee\myprogram\other\class\singletons.phpon line 31
ネットから生まれたものです。
シングルケースモードの3つのポイント:
(1)保存クラスの一意のインスタンスを必要とする静的メンバ変数:
 

private static $_instance;
(2)構造関数とクローン関数は、プライベートとして宣言しなければならない。外部プログラムnew類を防止し、単一の例モードを失う意味:

private function __construct()
 {
   $this->_db = pg_connect('xxxx');
 }
 private function __clone()
 {
 }//  __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(...);//  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(...);
?>

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();
//$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についてもっと興味のある読者は、本駅のテーマを見てもいいです。「php対象プログラム設計入門教程」、「PHP配列(Aray)操作テクニック大全」、「PHP基本文法入門教程」、「PHP演算と演算子の使い方のまとめ」、「php文字列(string)使い方のまとめ」、「php+mysqlデータベース操作入門教程」および「phpよくあるデータベースの操作技巧のまとめ
本論文で述べたように、皆さんのPHPプログラムの設計に役に立ちますように。