我的 php 项目中的单例模式 returns 第二次是一个空对象

Singleton pattern in my php project returns an empty object in second time

我的项目中有两个 类。 Db.php :

<?php

namespace app\core;

use \PDO;


class Db
{

    private $dsn = 'mysql:host=localhost;dbname=test';
    private $user = 'root';
    private $password = '6ReA4';
    private $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ];
    private static $PDO = null;

    private function __construct()
    {
      try {
            self::$PDO = new \PDO($this->dsn,$this->user,$this->password, $this->options);

          } catch (\PDOexception $e) {

             /*  Exception of datebase connection  (error message in future)  */
                echo "Date base connection error ".$e->getMessage();
              }
    }
    private function __clone() {}
    private function __wakeup () {}
    public static function conDb()
    {
      if (is_null(self::$PDO)) {
        return new self();
      } else { return self::$PDO; }
    }
}

和Model.php

<?php

namespace app\core;

class Model
{
  private $db;
  private $db2;
  public function __construct()
  {
    $this->db2 = Db::conDb();
    $this->db = Db::conDb();
        if ($this->db == $this->db2) {
          echo "Singleton works";
        } else { echo "Fail"; }
  }
  public function getById()
  {
  }
  public function getAll()
  {
  }

}
  private $db;
  private $db2;
  public function __construct()
  {
    $this->db2 = Db::conDb();
    $this->db = Db::conDb();
        if ($this->db == $this->db2) {
          echo "Singleton works";
        } else { echo "Fail"; }
  }
  public function getById()
  {
  }
  public function getAll()
  {
  }

}

我正在尝试实现单例模式,但方法 conDb() 在模型对象创建期间 returns 第二次是一个空对象,而不是同一个对象。请帮助我了解问题所在,我该如何解决?我做错了什么?

问题出在 Db class 定义中。您第一次调用 conDb 时,它返回了一个新的 Db 对象,该对象随后为静态变量分配了一个 PDO 对象。

第二次调用该方法时,您会返回一个 PDO 对象,该对象使 if 保护评估为假,因为 Db 对象和 PDO 对象不同。如果您调用它超过 2 次,此后返回的对象将是 PDO 对象并测试是否为真。

下面建议更改 Db class。

class Db
{

    private $dsn = 'mysql:host=localhost;dbname=test';
    private $user = 'root';
    private $password = '6ReA4';
    private $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    ];
    private static $PDO = null;

    private function __clone()
    {
    }
    private function __wakeup()
    {
    }

    public static function conDb()
    {
        // This is always null the first call
        if (is_null(self::$PDO)) {
            // Here you returned a new Db object.
            // return new self(); // <- old line.
            try {
                self::$PDO = new \PDO($this->dsn, $this->user, $this->password, $this->options);
            } catch (\PDOexception $e) {
                "Date base connection error " . $e->getMessage();
            }
        }

        // Here you returned a PDO object in an else, this can just be the variable after the PDO object is created.
        return self::$PDO;
    }
}

在模型的构造中,if 将评估为错误测试 Db 对象与 PDO 对象。

public function __construct()
{
    $this->db2 = Db::conDb();
    $this->db = Db::conDb();
    if ($this->db == $this->db2) {
        echo "Singleton works";
    } else { 
        echo "Fail"; 
    }
}