Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.1k views
in Technique[技术] by (71.8m points)

model view controller - Singleton pattern in my php project returns an empty object in second time

i have two classes in my project. Db.php :

<?php

namespace appcore;

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; }
    }
}

and Model.php

<?php

namespace appcore;

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()
  {
  }

}

I'm trying to realize singleton pattern but method conDb() during the Model object creation returns an empty object a second time instead of the same one. Please help me to understand what is the problem and how can i solve this? What am i doing wrong?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The issue resides in the Db class definition. The first time you called conDb it returned a new Db object that then assigned the static variable a PDO object.

The second time you call that method you get back a PDO object which made the if guard evaluate to false, since a Db object and PDO object are different. In case you call it more than 2 times the objects returned thereafter would be PDO objects and tested for true.

Below a suggested change to the 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;
    }
}

In the construction of the Model, the if would evaluate to false testing a Db object vs a PDO object.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...