Heim >Backend-Entwicklung >PHP-Tutorial >Analyse der Vorteile des PHP-Singleton-Modus

Analyse der Vorteile des PHP-Singleton-Modus

小云云
小云云Original
2018-03-03 14:01:021783Durchsuche

1. Was ist das Singleton-Muster?

1. Bedeutung
Als Objekterstellungsmodus stellt der Singleton-Modus sicher, dass es nur eine Instanz einer bestimmten Klasse gibt, und er instanziiert sich selbst und stellt diese Instanz global dem gesamten System zur Verfügung. Es wird keine Kopie der Instanz erstellt, sondern eine Referenz auf die in der Singleton-Klasse gespeicherte Instanz zurückgegeben.

Drei Schlüsselpunkte des Singleton-Musters:

(1) Eine statische Mitgliedsvariable ist erforderlich, um die einzige Instanz der Klasse zu speichern:

private static $_instance;




(2) Konstruktoren und Klonfunktionen müssen als privat deklariert werden, um zu verhindern, dass externe Programme neue Klassen erstellen und dadurch die Bedeutung des Singleton-Modus verlieren:

private function __construct()   
{   
    $this->_db = pg_connect('xxxx');  
}   
private function __clone()  
{  
}//覆盖__clone()方法,禁止克隆



(3). Für den Zugriff auf diese Instanz muss eine öffentliche statische Methode (normalerweise die getInstance-Methode) bereitgestellt werden, wodurch ein Verweis auf die eindeutige Instanz zurückgegeben wird

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


2, Warum den Singleton-Modus verwenden?

Die meisten Leute verstehen den Zweck des Singleton-Musters aus seiner wörtlichen Bedeutung und denken, dass es Systemressourcen spart, wiederholte Instanziierung vermeidet und eine Art „Familienplanung“ darstellt. Und jedes Mal, wenn die Seite ausgeführt wird, Alle Ressourcen werden aus dem Speicher gelöscht. Daher muss der Singleton in PHP bei jeder Ausführung neu instanziiert werden, wodurch die Bedeutung einer wiederholten Instanziierung des Singletons verloren geht. In dieser Hinsicht ist der Singleton in PHP tatsächlich so etwas enttäuschend. Aber hat ein Singleton nur diese Funktion und Anwendung?

Die Anwendung von PHP findet hauptsächlich in Datenbankanwendungen statt, daher gibt es in einer Anwendung eine große Anzahl von Datenbankoperationen. Wenn Sie den Singleton-Modus verwenden, ist die Entwicklung objektorientiert kann eine große Anzahl neuer Ressourcen vermieden werden.
Wenn eine Klasse benötigt wird, um bestimmte Konfigurationsinformationen im System global zu steuern, kann sie einfach im Singleton-Modus implementiert werden. Weitere Informationen finden Sie im FrontController-Teil von zend Framework.
In einer Seitenanforderung ist das Debuggen einfach, da der gesamte Code (z. B. die Datenbankoperationsklasse db) in einer Klasse konzentriert ist. Wir können Hooks in der Klasse setzen und Protokolle ausgeben, um var_dump und echo überall zu vermeiden. 1. Nachteile von PHP:


PHP ist eine interpretierte Skriptsprache. Dieser Betriebsmechanismus führt dazu, dass alle zugehörigen Ressourcen nach der Interpretation und Ausführung jeder PHP-Seite recycelt werden. Mit anderen Worten: PHP hat keine Möglichkeit, ein Objekt auf Sprachebene im Speicher zu speichern. Dies unterscheidet sich von kompilierten Typen wie asp.net und Java. In Java existiert beispielsweise immer ein Singleton Die Variablen sind seitenübergreifend und können diese Instanz im Anwendungslebenszyklus wirklich einzigartig machen. Allerdings sind in PHP alle Variablen, egal ob es sich um globale Variablen oder statische Mitglieder der Klasse handelt, auf Seitenebene. Jedes Mal, wenn die Seite ausgeführt wird, wird ein neues Objekt neu erstellt und nach der Ausführung der Seite gelöscht. Es scheint, dass PHP Der Singleton-Modus ist bedeutungslos, daher denke ich, dass der PHP-Singleton-Modus nur dann sehr sinnvoll ist, wenn mehrere Anwendungsszenarien in einer einzelnen Anforderung auf Seitenebene auftreten und dieselbe Objektressource gemeinsam nutzen müssen.

2. Anwendungsfälle des Singleton-Modus in PHP:

(1) Interaktion zwischen Anwendung und Datenbank

In einer Anwendung wird es eine große Anzahl von Datenbankoperationen geben, z as Um über ein Datenbankhandle eine Verbindung zur Datenbank herzustellen, kann durch die Verwendung des Singleton-Modus eine große Anzahl neuer Vorgänge vermieden werden, da jeder neue Vorgang Speicherressourcen und Systemressourcen verbraucht.

(2) Konfigurationsinformationen steuern

Wenn eine Klasse benötigt wird, um bestimmte Konfigurationsinformationen im System global zu steuern, kann sie einfach mithilfe des Singleton-Modus implementiert werden.

3. Wie implementiert man den Singleton-Modus?

1. Häufige Beispiele für den Datenbankzugriff:


<?php  
......  
//初始化一个数据库句柄  
$db = new DB(...);  
   
//添加用户信息  
$db->addUserInfo(...);  
   
......  
   
//在函数中访问数据库,查找用户信息  
function getUserInfo()  
{  
    $db = new DB(...);//再次new 数据库类,和数据库建立连接  
    $db = query(....);//根据查询语句访问数据库  
}  
   
?>
td >
<?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(...); ?>

下面的代码是PDO操作数据库类的一个封装,采用了单例模式:


e805f2cab7c01f804689bf075158c337dsn = 'mysql:host='.$dbHost.';dbname='.$dbName;

            $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd);

            $this->dbh->exec('SET character_set_connection='.$dbCharset.', character_set_results='.$dbCharset.', character_set_client=binary');

        } 7ada43ee74c1dbbf3cd559fccdb665f8catch5db79b134e9f6b82c0b36e0489ee08ed (PDOException $e) {

            $this->outputError($e->getMessage());

        }

    }

     

    /**

     * 防止克隆

     * 

     */

    private function __clone() {}

     

    /**

     * Singleton instance

     * 

     * @return Object

     */

    public static function getInstance($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)

    {

        if (self::$_instance === null) {

            self::$_instance = new self($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset);

        }

        return self::$_instance;

    }

     

    /**

     * Query 查询

     *

     * @param String $strSql SQL语句

*@param String $ queryMode 查询 方式 (alle oder zeile)

*@param boolean $ debug

*@return Array

*/

    public function query($strSql, $queryMode = 'All', $debug = false)

    {

        if ($debug === true) $this->debug( $strSql);

        $recordset = $this->dbh->query($strSql);

        $this->getPDOError();

        if ($recordset) {

            $recordset->setFetchMode(PDO::FETCH_ASSOC);

            if ($queryMode == 'All') {

                $result = $recordset->fetchAll() >  & 🎜>    }

     

    /**

* Update Update

*

* @param String $table Tabellenname

* @param Array $arrayDataValue Felder und Werte

* @param String $where Bedingung

* @param Boolean $debug

* @return Int

*/

    public function update($table, $arrayDataValue, $where = '', $debug = false)

    {

        $this->checkFields($table, $arrayDataValue);

        if ($where) {

            $strSql = '';

096199f75bf10ac807db896fb4430706foreach5db79b134e9f6b82c0b36e0489ee08ed ($arrayDataValue as $key => $value) {

                $strSql .= ", `$key`='$value'";

            }

            $ strSql = bcce8afdbf6c4f6f25f33a5727a432desubstr5db79b134e9f6b82c0b36e0489ee08ed($strSql, 1);

            $strSql = "UPDATE `$table` SET $strSql WHERE $where";

        } else {

            $strSql = "REPLACE INTO `$table` (`".implode('`,`', array_keys ($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";

        }

        if ($debug == = true) $this->debug($strSql);

        $result = $this->dbh->exec($strSql);

        $this->getPDOError ();

        return $result;

    }

     

    /**

* Einfügen einfügen

*

* @param String $table Tabellenname

* @param Array $arrayDataValue Felder und Werte

* @param Boolean $debug

* @return Int

*/

    public function insert($table, $arrayDataValue, $debug = false)

    {

        $this-> checkFields($table, $arrayDataValue);

        $strSql = "INSERT INTO `$table` (`".implode('`,`', array_keys($arrayDataValue))."`) VALUES (' ".implode("','", $arrayDataValue)."')";

        if ($debug === true) $this->debug($strSql);

        $result = $this->dbh->exec($strSql);

        $this->getPDOError();

        return $result;

}

     

    /**

* Überschreibmodus ersetzen, um

*

* @param String $table Tabellenname

* @param Array $arrayDataValue Felder und Werte

* @param Boolean $debug

* @return Int

*/

    public function replace($table, $arrayDataValue, $debug = false)

    {

        $this->checkFields($table, $arrayDataValue);

        $strSql = "REPLACE INTO `$table`(`".implode('`,`', array_keys($ arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";

        if ($debug === true) $this->debug ($strSql);

        $result = $this->dbh->exec($strSql);

        $this->getPDOError();

return $result;

    }

     

    /**

* Löschen Löschen

*

* @param String $table Tabellenname

* @param String $where Bedingung

* @param Boolean $debug

* @return Int

*/

    public function delete($table, $where = '', $debug = false)

    {

        if ($where == '') {

            $this->outputError("'WHERE' is Null");

        } else {

            $strSql = "DELETE FROM `$table` WHERE $where";

            if ($debug === true) $this-> debug($strSql);

            $result = $this->dbh->exec($strSql);

            $this->getPDOError();

            return $result;

        句

     *

     * @param String $strSql

     * @param Boolean $debug

     * @return Int

     */

    public function execSql ($ strSql, $debug = false)

    {

        if ($debug === true) $this->debug($strSql);

        $result = $ this->dbh->exec($strSql);

        $this->getPDOError();

        return $result;

    }

     

    /**

* Maximalwert des Feldes abrufen

* 🎜> * @param string $where Bedingung

*/

    public function getMaxValue($table, $field_name, $where = '', $debug = false)

    {

        $strSql = "SELECT MAX(".$field_name.") AS MAX_VALUE FROM $table";

        if ($where != '') $strSql .= " WHERE $where ";

        if ($debug === true) $this->debug($strSql);

        $arrTemp = $this->query($strSql, 'Row' );

        $maxValue = $arrTemp["MAX_VALUE"];

        if ($maxValue == "" || $maxValue == null) {

            $maxValue = 0;

        

    öffentliche Funktion getCount($table, $field_name, $where = '', $debug = false)

    {

        $strSql = "SELECT COUNT($field_name) AS NUM FROM $table";

        if ($where != '') $strSql .= " WHERE $where";

        if ($debug === true) $this->debug ($strSql);

        $arrTemp = $this->query($strSql, 'Row');

        return $arrTemp['NUM'];

}

     

    /**

* Anzahl der angegebenen Spalten abrufen

* @param string $where

* @param bool $debug

* @return int

*/

    öffentliche Funktion getTableEngine($dbName, $tableName)

    {

$strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name='".$tableName."'";

        $arrayTableInfo = $this->query($strSql);

        $this->getPDOError();

        return $arrayTableInfo[0]['Engine'];

    }

     

    /**

* beginTransaction Transaktion beginnt

*/

    private function beginTransaction()

    {

   &   ()

    {

        $this->dbh->commit();

    }

     

    /**

* Transaktionsübermittlung festschreiben

*/

    private function rollback()

    {

        $this->dbh->rollback();

    }

     

    /**

* Rollback-Transaktions-Rollback

*/

    public function execTransaction($arraySql)

    {

        $retval = 1;

        $this->beginTransaction();

        foreach ($arraySql as $strSql) {

            if ($this->execSql($strSql) == 0) $retval = 0;

        }

        if ($retval == 0) {

            $this->rollback();

return false;

        } else {

            $this->commit();

            return true;

        }

    }

    /**

* Transaktion verarbeitet mehrere SQL-Anweisungen über Transaktionen

* Vor dem Aufruf müssen Sie mit getTableEngine ermitteln, ob die Tabellen-Engine Transaktionen unterstützt

*

* @param array $arraySql

* @return Boolean

*/

    private function checkFields($table, $arrayFields)

    {

        $fields = $this-> ;getFields($table);

        foreach ($arrayFields as $key => $value) {

            if (!in_array($key, $fields)) {

                $this->outputError("Unbekannte Spalte `$key` in der Feldliste.");

            

    private Funktion getFields($table)

    {

        $fields = array();

        $recordset = $this->dbh->query( "SHOW COLUMNS FROM $table");

        $this->getPDOError();

        $recordset->setFetchMode(PDO::FETCH_ASSOC);

        $ result = $recordset->fetchAll();

        foreach ($result as $rows) {

            $fields[] = $rows['Field'];

        

    {

        if ($this->dbh->errorCode() != '00000') {

            $arrayError = $this->dbh- >errorInfo();

            $this->outputError($arrayError[2]);

        }

    }

     

    /**

* getPDOError erfasst PDO-Fehlerinformationen

*/

    private function debug($debuginfo)

    {

        var_dump($debuginfo);

        exit( );

    }

     

    /**

     * debug

     * 

     * @param mixed $debuginfo

     */

    private function outputError($strErrMsg)

    {

        throw new Exception('MySQL Error: '.$strErrMsg);

    }

     

    /**

* Fehlermeldung ausgeben

*

* @param String $strErrMsg

*/



调用方法:

1

2

3

4

5

6

e44913b555daf08576c8840c56bd4e0cquery("8f810545c6213f9f7d68a3dd31d329e9select5db79b134e9f6b82c0b36e0489ee08ed count(*) frome table");

$db->destruct();

?>

123456
$db->destruct();?>

Das obige ist der detaillierte Inhalt vonAnalyse der Vorteile des PHP-Singleton-Modus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn