什么是PHP中的单例?

kar*_*ain 8 php

对许多人来说,这个问题可能真是个愚蠢的问题.但是,我无法找到它的确切答案.

什么是PHP中的单例类?

我经历了很多教程,仍然不明白它的确切含义.我的理解是它不能被多次实例化.该对象将被共享.那个的真实意义是什么?假设单例实现了数据库连接,是否意味着,如果'A'访问该站点并登录.同时说'B'尝试登录,B将无法登录,直到A登录并释放该对象?

Hem*_*ale 16

  • Singleton可以像全局变量一样使用.
  • 与普通类不同,它只能有一个类的实例(对象).
  • 当我们不想创建一个类的数据库连接或实用程序库的多个实例时,我们会选择单例模式.
  • Singleton确保您永远不会有多个类的实例.
  • 将构造方法设为私有以生成类Singleton.
  • 如果您不想实例化类的多个副本但只想实例化一个,那么您只需将其置于单例模式中即可调用该类的方法,即使您创建了该类,它也只能在内存中创建一个副本另一个例子.
  • 如果用户只想连接到数据库,那么如果实例已经存在则无需再次创建另一个实例,您可以只使用第一个对象并进行连接.

例如

<?php
    class DBConn {

        private static $obj;

        private final function  __construct() {
            echo __CLASS__ . " initializes only once\n";
        }

        public static function getConn() {
            if(!isset(self::$obj)) {
                self::$obj = new DBConn();
            }
            return self::$obj;
        }
    }

    $obj1 = DBConn::getConn();
    $obj2 = DBConn::getConn();

    var_dump($obj1 == $obj2);
?>
Run Code Online (Sandbox Code Playgroud)

输出:

DBConn initializes only once
bool(true)
Run Code Online (Sandbox Code Playgroud)

Object1和Object2将指向同一个实例

            _______________________
           |                       |
$obj1 ---->|  Instance of DBConn   |<----- $obj2
           |_______________________| 
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!! :)


Don*_*sto 13

单例是一种特殊的类,正如您所说,只能实例化一次.

第一点:它不是PHP相关概念,而是OOP概念.

什么"只实例化一次意味着什么?" 它只是意味着如果该类的对象已经实例化,系统将返回它而不是创建新的对象.为什么?因为,有时候,你需要一个"通用"实例(全局实例),或者因为实例化已存在对象的"副本"是无用的.

让我们首先考虑一个框架:在引导操作上,您需要实例化一个对象,但您可以(必须)与其他请求框架引导程序共享它.

对于第二种情况,让我们考虑一个只有方法而没有成员的类(所以基本上没有内部状态).也许您可以将它实现为静态类,但如果您想要遵循设计模式,请考虑使用AbstractFactory),您应该使用对象.因此,拥有只有方法的同一对象的一些副本是不必要的,也是内存浪费.

这是我使用单身人士的两个主要原因.


小智 5

是的,你是对的“它不能被实例化多次”。当您打开数据库连接时,这个概念非常有用。

认为,

如果有人登录,您将创建新的数据库对象。

如果有人更新某些内容,您将创建一个新的数据库对象。

如果有人注销,您将创建一个新的数据库对象。

正如您所看到的,每次与数据库交互时,都会创建一个新对象并打开一个新连接。就效率而言,这是一件坏事。

这里单例类真正解决了问题。它创建一个数据库连接对象并保存它,只要需要,它就返回它而不是创建一个新的。

class DB{
private static $_instance = null;
private $_pdo;

        private function __construct(){
            try{
                $this->_pdo = new PDO('mysql:host ='yourhost'; dbname = 'your_database','username','password);
                echo 'connected';

            }catch(PDOException $e){
                die($e->getMessage());
            }
        }
      public static function getInstance(){
          if(!isset(self::$_instance)){
              self::$_instance = new DB();
    }
    return self::$_instance; 
     }
  }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,此类检查现有连接($_instance 属性),如果未设置则返回它。