gpt4 book ai didi

php - PDO 语句属性存储为对象属性并由对象方法访问

转载 作者:行者123 更新时间:2023-12-04 05:16:26 26 4
gpt4 key购买 nike

我知道标题并没有提供太多关于我所要求的线索,所以这里是简化的情况:

class MyPDO extends PDO
{
private $stmt;

function __construct($dsn...)
{
parent:__construct($dsn...);
}

function myQuery($sql)
{
$this->stmt = $this->query($query);
}

function myFetchAll()
{
return $this->stmt->fetchAll($mode);
}

function myFetchRow()
{
return $this->stmt->fetch();
}

}

在整个应用程序中,我有一个 MyPDO 的基本实例并将其传递给不同的对象、映射器。
$adapter = new MyPDO($dsn...);
$adapter->myQuery('SELECT * FROM table');
$rows = $adapter->myFetchAll();

$another_object = new ObjectThatNeedsPDO($adapter);
$another_object->adapter->myQuery('SELECT * from another_table');
$rows = $another_object->adapter->myFetchAll();

这种方法安全吗,尤其是从 MyPDO::stmt 的角度来看?应用程序流程是否会搞砸,所以我最终可以从另一个 $stmt 获取数据而不是预期?

最佳答案

就个人而言,我不会采取你的方法。原因是我不希望一个类创建的语句对象暴露给另一个不相关的类。此外,每个实现类可能有不同类型的参数绑定(bind),它需要执行,它需要访问数据的方式(即获取所有行,获取每一行,作为对象与数组获取等),方式以特定于类的方式处理错误,等等。

对我来说,通过在基本 PDO 类的某个子类中包含此逻辑,您一无所获。我的意思是真的很难做到:

$stmt = $this->pdo->query(...)
$data = $stmt->fetchAll();

比:
$this->myPDO->query(...);
$data = $this->myPDO->myFetchAll();

除了将这个额外的类不必要地耦合到将使用它的所有类之外,您还能获得什么?实际上,语句交互总是非常特定于类,只有基本 PDO 实例提供的唯一通用功能(DB 连接)。

因此,当然可以随意在类之间传递一个公共(public) PDO 实例,这绝对是一个好习惯(即依赖注入(inject))。

仔细考虑一下,当您对提议的 myPDO 类进行更改时,您是否希望潜在地更改每个实现类,或者您是否想在每次某些实现类需要一些自定义方式与语句对象交互时更改您的 myPDO 类。

根据下面的讨论,您可能需要考虑扩展 PDOStatement 以提供最大的灵 active 。

这可能看起来像这样:
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();

关于php - PDO 语句属性存储为对象属性并由对象方法访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203539/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com