这是多么懒惰的数据库连接连接应该是什么?

时间:2014-05-11 17:18:01

标签: php pdo lazy-loading

所以我做了一些关于在OOP中连接数据库的好方法的研究。如果你在我的数据库模型中查看我的connect()方法,我只会在我要查询时连接,如果没有连接则。我认为它被称为懒惰的连接,我在SO answer上偶然发现了它。

是不是只为整个应用程序建立 1 数据库连接?

如果我在文件A中new Database()和文件B中的new Database(),那么仍然会有两个连接。

如果有任何帮助,我正在使用微型MVC框架。

class Database
{
    private $pdo;
    private $host;
    private $databse;
    private $username;
    private $password;

    public function __construct()
    {
        $this->host     = Config::get('mysql/host');
        $this->database = Config::get('mysql/database');
        $this->username = Config::get('mysql/username');
        $this->password = Config::get('mysql/password');
    }

    public function query($sql, $params)
    {
        $this->connect();

        $sth    = $this->pdo->prepare($sql);
        $params = is_array($params) ? $params : [$params];

        if ($sth->execute($params)) {
            return $sth->fetch(PDO::FETCH_OBJ);
        }
    }

    private function connect()
    {
        if (!$this->pdo) {
            try {
                $this->pdo = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database . ';charset=utf8', $this->username, $this->password);
            } catch (Exception $e) {
                die($e->getMessage());
            }
        }
    }
}

4 个答案:

答案 0 :(得分:1)

我很乐意评论上述答案,但声誉让我无法这样做。然而,我必须确保人们不会阅读这些并认为这是真实或良好的做法。

关于主题: 单个数据库连接的想法是好的,直到它没有。您可能必须连接到第二个,然后单个将阻碍您这样做。 配置也应该使用真实参数:

  1. 您希望能够创建多个连接而不能,因为类Config不允许它。
  2. 此类与'mysql/host'
  3. 很难结合
  4. Config一样需要在你的代码周围浮动魔术字符串也不是一个好主意。有人可能会出现并喜欢在配置中以不同方式调用它。如果您只使用参数来配置该问题就会消失。
  5. 您希望能够清楚地看到类具有的依赖关系。隐藏它需要import React, { Component } from "react"; class Save extends Component{ saveCanvas() { const canvasSave = document.getElementById('resetCanvas'); const d = canvasSave.toDataURL('image/png'); const w = window.open('about:blank', 'image from canvas'); w.document.write("<img src='"+d+"' alt='from canvas'/>"); console.log('Saved!'); } render(){ return( <div> <button onClick={ this.saveCanvas }>Save</button> </div> ) } } export default Save; 并且使用它4个参数的事实只会迫使您每次想要使用它时都要查看实现。
  6. 关于在会话中存储连接:

    1. 有什么意义?你不能为另一个PHP运行保护它。
    2. 序列化是不可能的,因为它是一种资源。
    3. 如上所述:如果您将会话中的对象存储在全局中,则可能会隐藏依赖项。
    4. http://php.net/manual/en/intro.session.php

答案 1 :(得分:0)

要只有一个类的实例,您需要单例模式

Creating the Singleton design pattern in PHP5

您可以轻松地将其添加到现有课程中。

答案 2 :(得分:0)

希望现在对这件事情有所了解还为时不晚。您正在混合两个概念 - 1.延迟加载(在这种情况下是延迟连接),以及2.持久连接。

只有在进行查询时,发布的代码才能正确建立实际的数据库连接。代码的正确性取决于代码的使用方式。请考虑以下伪调用:

  1. 实例化Database类,该类调用构造函数
  2. 显式调用connect函数
  3. 提出查询
  4. 上述序列使惰性连接的好处无效,因为无论如何都会建立连接。但是,如果删除了第2步,则查询函数将调用connect,然后将创建与数据库的真实连接。

    为什么这有用?在复杂项目中,连接处理程序通常包含在某个头文件中。数据库查询是在各种组件中进行的。在进行查询时,必须准备好数据库连接。因此,即使在不从数据库加载任何内容的页面上也会创建连接。请记住,TCP连接是宝贵的服务器资源。建立太多未使用的连接只是浪费。一种惰性连接方法正好解决了这个问题。

    持久连接是一个不同的概念。这意味着在页面会话结束时,连接未关闭。当需要新的连接时,PHP会寻找一个相同的&#34;连接到重用。

    为了完整起见,我想指出持久连接也与连接池不同,尽管持久连接可以被视为1的连接池。

答案 3 :(得分:-1)

如果将新Database()的结果存储在全局变量中,那么您可以重复使用它,并为整个应用程序提供单个连接。

如果你在文件A中创建新的Database()和在文件B中创建新的Database(),那么你是正确的。会有两个连接。

您的代码的整体概念与我使用的类似,并且效果很好。