0

假设我有一个名为 Books 的课程。在该类中,我有一个方法可以获取一本书或几本书的标题、价格和类别。所以是这样的:

public function fetchRows () {
  $sql = $con->prepare("SELECT Title, Price, Category FROM Books");
  $sql->execute();
  return $sql->fetchAll();
}

一切都很好,但是可以说我现在想获取另一行,order结果和limit返回的行数。为此编写另一种方法会起作用,但这会导致方法数量荒谬,而且这很混乱并且不符合 DRY 规则。我可以使用参数来自定义准备语句,然后我可能最终会在一个参数中编写整个查询,而且这似乎也不可靠和干净。

我的问题是我如何编写/构造方法/类来适应最终用户想要得到的东西?

抱歉,这真的不是针对特定问题的问题。我已经阅读了一些关于我的问题的材料,但是我很难将这种模式缠绕在我的脑海中,我希望有人可以提供一个解释或示例来帮助我理解这一点。

4

2 回答 2

1

您是否考虑过使用位于数据库顶部的 ORM(对象关系映射器)?我强烈推荐 Doctrine 2 http://www.doctrine-project.org。这样,您可以将数据库表中的行视为对象:所有数据库交互都被抽象出来(如果需要,您仍然可以直接运行 SQL 查询)。

如果您不熟悉 ORM 的概念,Doctrine 使您能够编写如下代码:

$user = new User();
$user->username = 'test';
$user->email = 'test@example.com';
$entityManager->persist($user);
$entityManager->flush();

您刚刚运行INSERT INTO user (username, email) VALUES ('test', 'test@example.com');而没有编写任何 SQL。

类似地,可以按如下方式检索用户:

$user = $entityManager->getRepository('User')->findOneByUsername('test')

$user = $entityManager->getRepository('User')->findOneByEmail('test@example.com')

这些查找器方法是根据用户表上存在的字段自动为您生成的,可帮助您保持代码 DRY。

于 2013-03-09T15:27:40.697 回答
-1

适应最终用户想要得到的东西?

你在这里进入摇摇欲坠的地方。您可能希望最终用户允许她访问数据库层,以便她可以准备查询。

否则你开始重新发明轮子。老实说,我怀疑你真的有那么多功能和那么多参数。

因此,这在很大程度上取决于您的最终用户。如果最终用户想做很多事情,请以源代码形式提供软件,以便最终用户可以根据需要修改软件。

在那之前,发布您的软件并从最终用户那里获得真正需要哪些功能的反馈。

也就是说,对于您的应用程序来说,ORM 可能只是一种无用的开销,但您只需要在 PDO 之上增加一些功能,例如延迟查询和稍后重命名列名的一些功能。

$result = PDOQuery::create('* FROM config')->limit(2);

$result->orderBy('`option`');

$result->aliasNames(['option' => 'name'], $removeOther = true);    

foreach ($result as $row) {
    print_r($row);
}

这只是示例性的,代码只会将行提供为关联数组:

Array
(
    [name] => Insert Option 50e60ca17bdf4
)
Array
(
    [name] => Insert Option A 50e78a79ead49
)

仅在涉及到 foreach 时执行(例如,您可以将其传递到视图中,如果视图不需要它,则永远不会执行数据库查询)。

您可以进一步扩展它,例如定义查询的所有内容都将成为您可以传递的查询定义。

您可以使迭代器成为堆叠迭代器,这样如果查询已被执行,您可以对结果应用限制,而不是再次运行查询。什么不是。

这实际上所做的只是根据您的需要增强 PDO 的接口,因此您需要自己编写该组件。

它也应该比上面示例代码中概述的更加解耦。

于 2013-03-09T15:32:53.513 回答