就个人而言,我不会采取你的方法。原因是我不希望一个类创建的语句对象暴露给另一个不相关的类。此外,每个实现类可能有不同类型的参数绑定,它需要执行,它需要访问数据的方式(即获取所有行,获取每一行,获取作为对象与数组等),方式以特定于类的方式处理错误,等等。
对我来说,通过在基本 PDO 类的某个子类中包含此逻辑,您将一无所获。我的意思是真的很难做到:
$stmt = $this->pdo->query(...)
$data = $stmt->fetchAll();
比:
$this->myPDO->query(...);
$data = $this->myPDO->myFetchAll();
除了将这个附加类不必要地耦合到所有将使用它的类之外,您还能获得什么?确实,语句交互总是非常特定于类,只有基本 PDO 实例提供的唯一通用功能(DB 连接)。
因此,当然可以随意在类之间传递一个公共 PDO 实例,这绝对是一个很好的做法(即依赖注入)。
仔细考虑一下,当您对提议的 myPDO 类进行更改时,您是否希望潜在地更改每个实现类,或者您是否想在每次某些实现类需要一些自定义方式与语句对象交互时更改您的 myPDO 类。
根据下面的讨论,您可能需要考虑扩展 PDOStatement 以提供最大的灵活性。
这可能看起来像这样:
class myPDOFactory {
public static function getInstance($dsn, $pdo_statement_class = 'myPDOStatement', $pdo_constructor_args = NULL);
$pdo = new PDO($dsn);
if (empty($pdo_statement_class)) {
$pdo_statement_class = 'PDOStatement';
}
if (empty($pdo_constructor_args) || !is_array($pdo_constructor_args)) {
$pdo_constructor_args = array();
}
$config_array = array($pdo_statement_class, $pdo_constructor_args);
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, $config_array);
return $pdo;
}
}
class myPDOStatement extends PDO Statement {
public function __construct(<any custom parameters you may need to have passed - items in $pdo_constructor_args from myPDOFactory class>) {
parent::__construct();
// any special stuff you want to do with any passed parameters here
}
public function fetchAll() {
// override any functionality you desire here
}
public function fetchAllObjects() {
return $this->fetchAll(PDO::FETCH_OBJ);
}
}
class someClassThatNeedsPDO {
protected $pdo = NULL;
public function __construct($pdo) {
if($pdo instanceof PDO) {
$this->pdo = $pdo;
} else {
throw new Exception('Ooops!');
}
}
public function doSomethingWithPDO() {
$stmt = $this->PDO->prepare('SELECT * FROM sometable');
$stmt = execute();
return $stmt->fetchAllObjects();
}
}
使用示例:
$pdo = myPDOFactory::getInstance($dsn, 'myPDOStatement', $constructor_args);
$consuming_class = new someClassThatNeedsPDO($pdo);
$object_array = $consuming_class->doSomethingWithPDO();