PHP:将对象用作数据库产品的有效方法

时间:2013-10-01 11:36:23

标签: php mysql database oop object

如果我的产品存储如下:

tbl_products
id, price, stock
1, 20, 5
2, 30, 5

文本在另一张桌子上:

tbl_texts
id, item_id, type, field, value
1, 1, 'product', 'name', 'Programming Book'
2, 1, 'product', 'description', 'A fine book'
3, 2, 'product', 'name', 'Bicycle'
4, 2, 'product', 'description', 'Goes very fast'

活动价格也在另一张桌子上:

tbl_product_campaign_prices
id, item_id, price, valid_from, valid_to
1, 1, 5, null, null
2, 2, 10, null, 2014-10-10

好的,这是我想象中的表格。

我想将产品作为对象处理,因为我并不总是希望得到与产品相关的所有数据,因为它的数据库很重,我很少需要访问所有数据。

例如,有时我只需要产品的名称或描述。有时我需要竞选价格。 tbl_products的基本信息将始终被提取。

真正的问题是;我对代码的选择是什么?我想出了一些:

1

$product_id = 1;
$fetch_name = 1;
$fetch_description = 0;
$fetch_campaign_prices = 0;
$product = ProductFactory::get($product_id, $fetch_name, $fetch_description,
           $fetch_campaign_prices);

// This takes a lot of space and is very impractical 
// when I have to add new data to be fetched.

// Worst case would be having to add a bunch 
// of null, null, null to get the last data.

2

// Same as 1. but adding all the $fetch_ into an array and only use 2 parameters on the
// get() function.

$product = ProductFactory::get($product_id, $fetch_array);

// Still pretty ackward way to fetch data but much easier to add stuff 
// since I don't have to add any new parameters

3

$data_to_fetch = array('name', 'description');
ProductFactory::Prepare($data_to_fetch);
$product = ProductFactory::get($product_id);

有没有一种常见的方法可以做到这一点?这样做的有效方法是什么?我从来没有做过这样的事情,这些都来自我的头脑。

感谢您即将提出的意见!

2 个答案:

答案 0 :(得分:0)

基本上,您正在询问如何表达一小组配置标志的子集。这与您使用它的数据库非常无关。

  1. 使用单独的参数:难以维护,在一个地方进行更改将需要在所有地方进行更改。但是,如果没有合理的默认值,这可能是有意义的。在这些情况下,让呼叫失败可能比做错事更好。

  2. 使用有序的参数数组:非常难看,因为你必须记住订单的含义,而且在调用不正确时甚至更难判断。不要那样做。

  3. 名单:非常灵活且易于阅读。这可能是python的做事方式。但是检查包含哪些值以及哪些值不需要进行多次字符串比较,因此这可能有点贵。但是,可能只是一个中型数据库查询。要考虑的一件事是是否检查被调用函数不知道的名称。您可以将这些报告为错误以避免拼写错误,或者您可以选择忽略它们,例如向前兼容性。

  4. 位掩码:正如Mark Ba​​ker指出的那样,您可以定义一些具有可读名称和值的常量,这两个常量是2的幂。您可以使用|一起构建单个值。然后,您可以使用按位并从函数中的组合值中提取单个位。这是做事的C方式。它具有高性能,拼写错误的危险性低。但它可能会用这些符号常量破坏你的命名空间。

  5. 配置对象:您可以为传递给该函数的参数定义一个类。你有设置器来设置各种标志。最重要的是,你有一个可以设置默认值的构造函数。因此,这里的关键好处是你可以建立合理的默认值,即使默认情况下应该提取某些内容而其他内容不应该,也不要调用FETCH_FOODONT_FETCH_BAR等常量名称。

  6. 我会去4。

答案 1 :(得分:0)

首先,我假设这是一个假设的例子 - 但要注意在性能和复杂性之间进行权衡 - 您可能会发现PHP代码中的额外复杂性成为维护问题。反过来,您可能还会发现额外的PHP代码超过了不加载其他数据的好处。

其次,大多数对象关系映射框架解决此问题的方式是通过“延迟加载”。 ORM只会在需要时从您的广告系列价格表中加载数据;这对开发人员来说几乎是透明的。

当然,这并不适用于您的“文本”表,它实际上是一个实体属性值存储。在这种情况下,它取决于您的文本架构是如何修复的。如果您知道您总是有“名称”和“描述”,则可以将其硬编码为位掩码。但是,这种设计往往会随着时间的推移而增长(否则,在产品表上有一个“名称”和“描述”列会更好)。在这种情况下,我坚持将文本类型作为字符串参数传递 - “name”,“description”。这意味着当您添加新文本类型 - “shortDescription”时 - 您不必重新访问productFactory代码以使其了解新文本类型。