5

我目前正在使用 PHP PDO 来访问我的数据库。这一切都工作得很好,花花公子。但是,我将在我的服务器设置中添加只读副本,因此我希望相应地调整我的代码。

我目前的行动计划是存储一组数据库凭据详细信息。为 MySQL 主数据库设置一个“读写”集,为“只读副本”设置任意数量的凭据。

我想做的是向 PDO 类添加一个名为“mode”的方法,其中通过模式传递,例如“read”或(默认)“write”。通过传递它(例如 $dbh->mode("read"); ),它可以查找随机只读副本的详细信息(不关心哪个)并将这些详细信息用于连接。然后,一旦我从我的副本中读取完毕,再执行一次 $dbh->mode("default") 将其放回写入模式,这样我就可以使用 INSERT、UPDATE 等。

这可以在不简单地破坏 PDO 对象并创建一个新对象的情况下完成吗?对象已经存在后可以简单地更改连接详细信息吗?

到目前为止,我有以下内容(几乎没有,但认为它是一个开始)。

Class SwitchablePDO extends PDO
{
    public function mode($mode = "default") 
    {
        // Use the credentials for my master read and write server by default

        if($mode == "read")
        {
            // Use one the credentials for my read replicas (randomly choose)
        }

    }
}

任何有关这方面的帮助将不胜感激!

4

2 回答 2

2

我宁愿设置完全不同的数据库连接对象而不是处理模式。使用模式,你不可避免地会遇到一段代码没有设置模式,依赖于前一段代码的模式,在不同的上下文中调用时会失败的情况。这称为顺序耦合

使用工厂方法或依赖注入容器提供的多个对象,您可以确保每段代码都指定它需要的数据库连接,例如 master 或 slave。

作为奖励,避免使用主/从作为名称,而是使用与要执行的任务类型相关的名称,例如分析,它允许您更改将使用哪个服务器,而无需通过代码查找所有相关部分的代码。

于 2012-07-27T13:41:14.657 回答
1

为读写模式创建单独的类,然后依次分配给 SwitchablePDO 类中的私有/受保护属性。然后调用mode()应该只设置要使用的属性。这是一些伪代码:

class WriteablePDO extends PDO
{
    // methods
}

class ReadablePDO extends PDO
{
    // methods
}

class SwitchablePDO
{
    protected $_mode = 'read'; // default
    protected $_read;
    protected $_write;

    public function __construct()
    {
        $this->_read = new ReadablePDO();
        $this->_write = new WriteablePDO();
    }

    public function mode($key)
    {
        if ($key === 'read')
        {
            $this->_mode = '_read';
        }
        elseif ($key === 'write')
        {
            $this->_mode = '_write';
        }
    }

    public function __call($method, $arguments)
    {
        return call_user_func_array(array($this->{$this->_mode}, $method), $arguments);
    }

}
于 2012-07-27T12:17:16.507 回答