【问题标题】:Using different mysql users within same class while maintaining same connection?在保持相同连接的同时在同一类中使用不同的 mysql 用户?
【发布时间】:2015-05-31 03:26:36
【问题描述】:

我处于需要使用 MYSQL 的LAST_INSERT_ID() 的情况,这显然只有在维护相同的连接时才有可能。但是当我考虑建立 PDO 连接的方式时,我突然想到我可能会遇到问题。

我有一个包含各种连接类型的数据库类。在这个类中,我根据我在 PDO 查询方法中调用的用户权限创建了不同的 PDO 连接方法,如下所示......

class dbFunctions {

    private $userSelect = "userSelect";
    private $passSelect = "XXXXX";
    private $userDelete = "userDelete";
    private $passDelete = "XXXXX";

    protected function connectSelect() {
        $dsn = $this->dsn();
        $this->pdo = new PDO($dsn, $this->userSelect, $this->passSelect, $this->options);

        return $this->pdo;
    }

    protected function connectDelete() {
        $dsn = $this->dsn();
        $this->pdo = new PDO($dsn, $this->userDelete, $this->passDelete, $this->options);

        return $this->pdo;
    }

    public function selectCount($query, $values = []) {

        $result = $this->connectSelect()->prepare($query);
        $result->execute($values);
        $exec = $result->fetch();

        $count = (int)$exec['total'];

        return $count;
    }
}

我的问题是……

  • 我是否最好为所有查询创建一个具有相同帐户/密码的全局连接对象?我这样做是出于安全目的,但我认为它可能有缺点。
  • 即使这些是不同的 PDO 连接对象,PHP 是否能够确定它们是同一脚本中同一会话的一部分?在这种情况下,单独的方法就可以了。
  • 如何让当前班级的 mysql 用户分开?

显然我可以自己测试,但我不确定当我让多个用户访问该网站时会产生什么结果。

【问题讨论】:

  • 您绝对不应该为 Web 应用程序的每个选择查询创建一个 PDO 实例,还是我误解了?
  • 所以我最好还是使用构造?
  • 我已将此标记为重复,不是因为它是同一个问题,而是因为另一个问题中的答案应该回答这个问题。
  • @Phil - 很明显,在更改标题和问题后,这些问题没有任何共同点。答案与其他问题中的任何其他答案都不同。我很清楚我问错了问题。
  • @EternalHour 感谢更新。我已经删除了欺骗

标签: php mysql class pdo


【解决方案1】:

最好是每页只有一个数据库连接。也许通过使用单例。

首先是为了性能,因为连接是有代价的。

在我看来,不存在任何安全问题。

【讨论】:

  • 有道理,但是因为我只创建一个类实例,然后在该实例中调用不同的方法,所以它不被认为是同一个连接吗?
  • 如果你在构造函数中实例化你的连接,并在你需要的时候一直使用它,有什么问题?
【解决方案2】:
  • 我是否最好为所有查询创建一个具有相同帐户/密码的全局连接对象?我这样做是出于安全目的,但我认为它可能有缺点。

我不是安全专家。我认为,如果我能够以只有某些人类帐户可以删除内容的方式管理 mysql 用户和权限,那就是某种安全性。我也认为这有许多复杂的后果。另一方面,如果需要,人们可以更新为空白字符串...

  • 即使这些是不同的 PDO 连接对象,PHP 是否能够确定它们是同一脚本中同一会话的一部分?在这种情况下,单独的方法就可以了。

PHP 对象似乎不是持久的。我们可以将它们序列化并使用__sleep() 来管理它们的存储。

它 [sleep] 可以清理对象,并且应该返回一个数组,其中包含该对象的所有应该序列化的变量的名称。

这部分你可能会感兴趣:

__wakeup() 的预期用途是重新建立在序列化期间可能丢失的任何数据库连接并执行其他重新初始化任务。

  • 如何让我的当前班级分开 mysql 用户?

使用相同的模式,但确保不要为每个选择或删除查询创建 pdo 实例。我对其进行了一些调整,以便为两个连接重用相同的功能。添加更多内容就像...命名新班级成员一样简单。

class dbFunctions {

    // other members

    // add these
    private $instanceSelect = null; // they default to null anyway
    private $instanceDelete = null;
    private $instanceFoosball = null;

    protected function connect($what) {
        if ($this->{"instance".$what} === null) { // true the first time
            $this->{"instance".$what} = new PDO($this->dsn(), $this->{"user".$what}, $this->{"pass".$what}, $this->options);
        }
        return $this->{"instance".$what}; // always reused
    }

    public function selectCount($query, $values = []) {}
}

$result = $this->connect('Select')->prepare($query);
$result = $this->connect('Foosball')->prepare($query);

【讨论】:

  • 感谢您的解释,很高兴我只需要做一个小修改。我确实知道每次使用问题中的代码都会生成一个新连接,这就是为什么我试图找到使用不同用户的正确方法。
  • 我对措辞感到高兴和抱歉,我并不是要居高临下。
  • 我无法理解您的建议是如何运作的。如果最初将所有值设置为 null,然后将其用于条件,它将始终为 true?
  • 第一次会是真的,所以然后分配一个PDO实例。第二次执行该函数时,属性仍然是您的 PDO 实例,条件评估为 false 并返回现有 PDO 实例
  • 我明白你的意思,我什至没有注意到你为连接对象分配了一个变量,而不是像我做的那样返回它:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 2013-04-11
相关资源
最近更新 更多