我是php的新手。能帮我找到正确安排以下任务的方法:
表“产品”
id - 详细信息
1 - 1-30,2-134:6:0 ;; 2-7:55:0 ;; 1-2,2-8:25:0 - 此字符串可以很长
2 -
3 - 1-360:17:0 ;; 1-361:185:0
每个产品1,2,3,...都存储在数据库中的一行中,尽管根据大小和颜色另外单独识别产品。这就是为什么有些产品可以拥有比其他产品更多的尺寸和颜色。
有时产品只有一种尺寸,但有些颜色。在这种情况下,这一个大小不存储在db中,而只存储在颜色中。
表格不规则填充。详细信息列不是必需的(可以为空)。
详细信息列以这种方式组成,例如:
1-30,2-134:6:0 ;; 2-7:55:0其中主分隔符为';;',因此该字符串将被分割为:
1-30,2-134:6:0
2-7:55:0
考虑到分裂的行,下一部分要分割:
1-30 - 第一部分
2-134 - 第二部分
6 - 第三部分
0 - 第四部分
第一部分,第三部分和第四部分总是出现。第二部分有时出现。
第一部分和第二部分可以从1-XXX或2-XXX开始。
第三部分是指库存产品的数量。
第四部分并不重要,可以忽略不计。
表“类型”
id - 值
1 - 产品
2 - 颜色
表“论据”
id - 值
1 - sr20 h12
2 - sr21 h13
3 - 蓝色
..
30 - sr25 h15
134 - 红色
考虑到上表,早期提到的例子意味着:
1-30表示1 =产品,30 = sr25 h15
2-134表示2 =颜色,134 =红色
请你帮我准备一下php脚本,这样可以正确显示产品:
产品1 - 尺寸:sr25 h15,颜色:红色,有货:6
产品1 - 尺寸:sr30 h16,颜色:蓝色,有货:13
产品1 - 尺寸:sr35 h20,颜色:粉红色,有货:2
产品2
产品3 - 颜色:白色,现货4
感谢Bill的建议,我将文件拆分为:
$ products = explode(“;;”,$ details);
foreach ...
$ fields = explode(“:”,$ products);
foreach ...
$ attribs = explode(“,”,$ fields);
foreach ...
但是,我不知道应该怎么用:
($ attrib_type,$ attrib_value)= explode(“ - ”,$ attribs [0]);
我还为参数准备了预加载的关联表,但我不知道如何使用它。
这是我的代码:
$ results = mysql_query(“SELECT id,name,details FROM products”) 或死('查询错误');
if(mysql_num_rows($ results)> 0) {
echo "<table width='780' cellpadding='2' border='1' rules='rows'>";
echo "<th width=50 align='left'>ID</th>";
echo "<th width=350 align='left'>Name</th>";
echo "<th width=380 align='left'>Details</th>";
while($r = mysql_fetch_array($results))
{
echo "<tr>";
echo "<td width=50 align='left'>".$r[0]."</td>";
echo "<td width=350 align='left'>".$r[1]."</td>";
//echo "<td width=350 align='left'>".$r[2]."</td>";
$string = "$r[2]";
$products = explode(';;', $string);
foreach ($products as $p)
{
$fields = explode(':', $p);
foreach ($fields as $f)
{
$attribs = explode(',', $f);
foreach ($attribs as $a)
{
$attrib_type_value = explode('-', $a);
foreach ($attrib_type_value as $t)
{
if ($t[0] == 1 or $t[0] == 2)
{
$query1 = mysql_query("SELECT products_type.id FROM products_type WHERE products_type.id ='$t'")
or die('error query1: ' . mysql_error());
$query2 = mysql_query("SELECT products_arguments.value FROM products_arguments WHERE products_arguments.id = '$t'")
or die('errur query2: ' . mysql_error());
if(mysql_num_rows($query1) > 0)
{
while($r2 = mysql_fetch_array($query1))
{
echo "<tr>
<td width=350 align='left'>".$r2[0]."</td>";
echo "</tr>";
}
}
}
}
}
}
}
echo "</tr>";
}
echo "</table>";
}
答案 0 :(得分:1)
更新:我将为您的问题提供另一个答案,但我会在下面留下原始回复。
您需要使用像explode()
这样的PHP函数来分隔“详细信息”字符串的元素。例如,假设您从数据库中获取了行并且$details
包含字符串,您可以将其分成如下所示的单个产品:
$products = explode(";;", $details);
然后您可以将产品字段分开:
$fields = explode(":", $products[0]);
然后您可以像下面这样分隔颜色,大小等属性:
$attribs = explode(",", $fields[0]);
然后你可以得到这样的颜色/大小的键:
($attrib_type, $attrib_value) = explode("-", $attribs[0]);
现在,您可以将$attrib_type
用于“颜色”与“尺寸”。您可以使用$attrib_value
在Arguments
表中查找。我建议通过主键将参数预加载到关联数组中,这样您就可以引用它们而无需运行额外的SQL查询。
这确实比你应该为这项任务做的工作多得多。
您非常需要数据库规范化。通过使用您展示的设计,您无法利用RDBMS在执行一致的结构化数据方面可以提供的强大功能。
首先,您需要创建一个表来记录每种类型的产品。
CREATE TABLE ProductTypes (
product_id SERIAL PRIMARY KEY,
description TEXT
);
INSERT INTO ProductTypes (product_id, description) VALUES
(1234, 'Pants'),
(3456, 'Shirts');
然后你需要一个每个SKU的表。此表记录了常见的产品信息,例如库存数量和价格。
CREATE TABLE ProductSkus (
product_sku CHAR(15) PRIMARY KEY,
product_id INT NOT NULL,
quantity INT NOT NULL,
price DECIMAL(9,2) NOT NULL,
UNIQUE KEY (product_id, product_sku),
FOREIGN KEY (product_id) REFERENCES ProductTypes(product_id)
);
INSERT INTO ProductSkus (product_sku, product_id, quantity, price) VALUES
('B001CKD28O', 1234, 33, 36.99), -- pants
('B001CKD270', 1234, 17, 34.99), -- pants
('B002DLD410', 3456, 8, 17.50); -- shirt
对于产品的每个子类型,您还需要一个表来记录特定于相应类型的属性。您可能还需要一些查找表,列出其中某些属性的允许值。
CREATE TABLE PantsSizes (
size VARCHAR(20) PRIMARY KEY
);
INSERT INTO PantsSizes VALUES ('sr25 h15'), ('sr20 h12'), ('sr21 h13');
CREATE TABLE PantsColors (
color VARCHAR(20) PRIMARY KEY
);
INSERT INTO PantsColors VALUES ('red'), ('blue');
CREATE TABLE Pants (
product_sku CHAR(15) PRIMARY KEY,
product_id INT NOT NULL CHECK (product_id = 1234) -- pants
size VARCHAR(20) NOT NULL,
color VARCHAR(20) NOT NULL,
FOREIGN KEY (product_id, product_sku) REFERENCES ProductSkus(product_id, product_sku),
FOREIGN KEY (size) REFERENCES PantsSizes(size),
FOREIGN KEY (color) REFERENCES PantsColors(color)
);
INSERT INTO Pants (product_id, product_sku, size, color) VALUES
(1234, 'B001CKD28O', 'sr25 h15', 'blue');
注意此表中的product_id
如何受CHECK
约束限制,而ProductSkus的外键是复合键。因此它只能 引用具有Pants产品类型的SKU。这样,您就不会意外地在引用衬衫SKU的裤子中创建一行。
现在要在PHP中显示裤子信息,你可以做这样简单的事情:
<?php
$pdo = new PDO(...connection...);
$stmt = $pdo->query("SELECT * FROM ProductSkus s
JOIN ProductTypes t USING (product_id)
JOIN Pants p USING (product_id, product_sku)");
?>
<table>
<tr>
<th>Product</th>
<th>Size</th>
<th>Color</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<?php while ($row = $stmt->fetch()) { ?>
<tr>
<td><?php echo $row['description']; ?></td>
<td><?php echo $row['size']; ?></td>
<td><?php echo $row['color']; ?></td>
<td><?php echo $row['quantity']; ?></td>
<td><?php echo $row['price']; ?></td>
</tr>
<?php } ?>
</table>
答案 1 :(得分:0)
这是一个很好的教程,可以用php进行拆分描述,但如果字符串中包含html标签会发生什么。
这是一个使用该条件的教程
http://phpschools.freehostia.com/other-stuff/split-html-description-in-php