如何确保我不在PHP类中重新创建多个数据库连接?

时间:2014-10-05 22:44:13

标签: php class mysqli

我还没有真正擅长这个,我试图解决这个问题,但似乎无法做到。

我正在尝试编写一个重用其数据库连接的PHP类,并且不会在每次需要时创建一个新类。我如何确保每次都不重新创建新连接?

请考虑下面的代码,如果我在PHP文件中创建多个连接或重复使用相同的连接,请告诉我。

由于

PHP文件

require_once(class.myclass.php);

$object = new myclass;

[...modify $object properties...]

if ($object->save_to_db()) {
  echo "OK \n";
}
else {
  echo "FAIL :" . $object->get_err();
}

[...modify $object properties...]

if ($object->save_to_db()) {
  echo "OK \n";
}
else {
  echo "FAIL :" . $object->get_err();
}

unset($object);

类文件

class myclass {

    private $id;
    private $db;                        // Database Connection
    private $err;                       // Error

    public function save_to_db() {

        $db = $this->get_db();

        $query = "...";

        if(!$db->execute($query)) {     
            $this->err = $db->get_err();
            $save_to_db = false;
        }
        else {
            $save_to_db = true;
        }

        unset($db);
        return $save_to_db;
    }

    private function get_db() {
        if (!isset($this->db)) {
            $this->db = new db;
        }
        return $this->db;
    }

    public function get_err() {
        return $this->err;
    }

    function __destruct() {
        if (isset($this->db)) {
          unset($this->db);
        }
    }

}

2 个答案:

答案 0 :(得分:-1)

有几种方法可以解决这个问题。通常,在创建“真实世界”应用程序时,您将使用一个体面的框架,它提供数据库连接和通用数据库功能作为依赖/服务。

但是在你玩游戏时,这些是一个简单用例最常见的:

A)Singleton设计模式。 (现在不鼓励使用单身人士来支持依赖注入,但为了玩/学习,使用它是可以接受的。)

B)将数据库连接分配给全局变量(即在任何函数的上下文之外),并在需要时使用global关键字将其导入。这看起来像这样:

$db = createMyConnection();

function iNeedTheDbConnection() 
{
    global $db;
    // here goes the code that uses the connection
}

这实际上甚至比单身人士更糟糕,但它仍然有效,并且仍然被广泛使用(例如在WordPress中)。

答案 1 :(得分:-1)

创建数据库处理程序的一个非常好的方法是使用返回自身的静态类方法。称为单身人士模式。

class DB {

  /**
   * Points to the instance of this class.
   * @var object
   */
  private static $instance = null;

  /**
   * Points to the database connection
   * @var object
   */
  private $db;

  /**
   * Initiates a new instance of self if one isn't set and opens a db connection
   * @return object an object of self
   */
  public static function getInstance() {
    if(self::$instance == null) {
      self::$instance = new self;
      $this->db = new PDO();
    }
    return self::$instance;
  }

  /**
   * Runs a query on the database
   * @param  string $query the query to run on the db
   * @return array         the result set
   */
  public function query($query) {
    // Query..
    $stmt = $this->db->prepare("SELECT * FROM table");
    $stmt->execute();
    return $stmt->fetchAll();
  }
}

简单的用法是:

$result = DB::getInstance()->query("SELECT * FROM table");
var_dump($result); // Outputs array of results.

这只会在您第一次调用DB :: getInstance()时打开一个连接。这样,您就不必启动课程并支持链接。 Laravel框架也使用此方法。

有很多方法可以做到这一点,正如lxg所说,单例方法是一种方法,但你也可以为类分配你在脚本运行时开始时打开的连接。

class NeedDB {

  /**
   * Points to the DB connection
   * @var object
   */
  private $db;

  /**
   * Class constructor
   * @param object $db The DB connection object
   */
  public function __construct($db) {
    $this->db = $db;
  }

  /**
   * Runs a query on the database
   * @param  string $query the query
   * @return array         the result set
   */
  public function query($query) {
    $stmt = $this->db->prepare($query);
    $stmt->execute();
    return $stmt->fetchAll();
  }
}

$db = new PDO();
$class = new NeedDB($db);

$result = $class->query("SELECT * FROM table");
var_dump($result);