我认为我在基本级别上获得了OOP范例,但我很难概念化在数据库中查找记录的正确方法。我怀疑这是因为我没有像我想的那样得到OOP ......
我正在尝试编写的应用程序是一个购物车,因为它有很多很好的候选对象。我将使用的对象是一个产品(是的,这是非常原始的)。
<?php
class Product
{
public $id = 0;
public $name = '';
public $price = 0;
function __construct($id)
{
// if $id exists try to retrieve
// a product with $id
// else create a new product
// and set $this->id
}
}
$product = new Product();
echo $product->name;
?>
够容易。但现在我想查找多个产品(搜索结果页面),我不知道如何处理它。
我倾向于编写另一个类,它接受一些输入并执行只返回产品ID列表的SQL查询。然后我会遍历这些结果并为每个结果创建一个产品对象。然后我可以遍历对象数组并构建我的搜索结果页面。
我不确定为什么,但这只是感觉不对劲。似乎太多的工作,因为首先我正在进行查询以获取产品ID列表,然后我会进行更多查询以获取每个产品的数据。如果只做一个返回我需要的所有数据的查询,它会快得多。
做什么是正确的?还有别的吗?
答案 0 :(得分:2)
编写一个不了解数据库的产品类(很难相信,但产品可以在没有数据库的情况下存在;))以及可以从数据库结果创建产品对象的类。 / p>
答案 1 :(得分:2)
从数据库到面向对象的应用程序的映射并非易事。有不同的方法可以解决这个问题,但一个简单的策略是拥有一个实体类(Product)和一个网关类(可以称为不同的东西,但通常是ProductGateway或ProductFinder)。网关类可以访问数据库,知道如何获取和初始化实体。同一个类也知道如何将对象映射回数据库。
例如:
class ProductGateway {
function getProductById($id) {
$result = $this->db->query("select * from products where id = ?", $id);
return new Product($result->next());
}
function save($product) {
if ($product->getId()) {
return $this->update($product);
} else {
return $this->insert($product);
}
}
...
}
关键是您的应用程序级代码不需要知道产品是否来自数据库。它只是更改实体对象并将其留给网关来处理持久性。
答案 2 :(得分:0)
我认为你正在考虑正确的方法 - 但有一点,为什么只返回id,返回匹配产品的数组(或列表)。
具有查询方法的ProductFinder如何,参数是产品的定义,返回类型是产品的集合。
然后您可能会看到ProductFinder也可以负责创建产品(插入数据库),删除产品等。因此,产品本身对数据库知之甚少或根本不知道。然后,ProductFinder可能会得到一个稍微不同的名称,例如ProductKeeper或ProductHome。
如果除了产品之外你还有很多实体,那么你可能会发现他们的“守护者”有很多共同的代码,不久你最终会得到一个持久性框架。似乎有least one already的php,我建议你看一下。
答案 3 :(得分:0)
不要反过来使用现有的框架来处理OOP中的数据库。 Zend_Db具有不同的使用方法,最值得注意的是表网关/行网关方法,如上所述。 TableGateway旨在执行查询并返回行。行代表一行,可以独立操作。
如果您正在对许多行进行查询,则表示该表的单独类(或者在某些复杂连接的情况下甚至是“虚拟”表)是保持该表和个人关注点的最简洁方法行分开。