我目前正在使用PHP PDO访问我的数据库。这一切都很顺利。但是,我将在服务器设置中添加读取副本,因此我希望相应地调整我的代码。
我目前的行动计划是存储一组数据库凭据详细信息。为MySQL主数据库设置一个"读写"集,并为"读副本"设置任意数量的凭据。
我想做的是在PDO类中添加一个名为"mode"的方法,其中通过一个模式,例如"read"或(默认)"write"。通过使其通过(例如$dbh->模式("读取");),它可以查找随机读取副本的详细信息(不考虑哪个),并将这些详细信息用于连接。然后,一旦我完成了对副本的读取,就执行另一个$dbh->模式("默认"),将其恢复到写入模式,从而可以使用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)
}
}
}
如有任何帮助,我们将不胜感激!
我宁愿设置完全不同的数据库连接对象,也不愿处理一种模式。使用模式时,您将不可避免地遇到这样的情况:一段代码没有设置模式,而是依赖于前一段代码的模式,并且在不同的上下文中调用时会失败。这就是所谓的顺序耦合。
对于工厂方法或依赖注入容器提供的多个对象,您可以确保每段代码都指定它需要的数据库连接,例如master或slave。
作为奖励,避免使用主/从名称,而是使用与要执行的任务类型相关的名称,如分析,它允许您更改将使用的服务器,而无需通过代码查找所有相关的代码片段。
为读写模式创建单独的类,然后将其分配给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);
}
}