分割字符串并排列数据库以在 PHP 中显示产品

发布于 2024-08-16 07:06:40 字数 3827 浏览 2 评论 0原文

我是 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, ... 都存储在数据库中一行,尽管产品还根据尺寸和颜色单独识别。这就是为什么有些产品可以比其他产品有更多的尺寸和颜色。 有时产品只有一种尺寸,但有某些颜色。在这种情况下,这一尺寸不存储在数据库中,而仅存储在颜色中。 桌子不规则地填满。详细信息列不是强制性的(可以为空)。 详细信息栏是这样组成的,例如:
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 的建议,我已按以下方式拆分归档:
$产品 = 爆炸(";;", $details);
foreach ...
$fields = Explode(":", $products);
foreach ...
$attribs = 爆炸(",", $fields);
foreach ...

但是,我不知道应该如何使用:
($attrib_type, $attrib_value) =explode("-", $attribs[0]);

我还准备了预加载的参数关联表,但我不知道如何使用它。

这是我的代码:

$results = mysql_query("从产品中选择 id、名称、详细信息") 或死('查询错误');

if(mysql_num_rows($结果) > 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>";

}

I'm new in php. Could you please help me to find the way to properly arrange following task:

Table "Products"
id - details
1 - 1-30,2-134:6:0;;2-7:55:0;;1-2,2-8:25:0 - where this string can be very long
2 -
3 - 1-360:17:0;;1-361:185:0

Every product 1, 2, 3, ... are stored in db in one row, although product is additionally recognized separately per size and color. That is why some products can have more sizes and colors then the others.
Sometimes product is only in one size but in some colors. In such case this one size is not stored in db but only colors.
Table is irregularly filled. The details column is not mandatory (can be empty).
The details column consists in this way, example:
1-30,2-134:6:0;;2-7:55:0 where main separator is ';;', so this string will be splited to:
1-30,2-134:6:0
2-7:55:0

Considering frist splited row, there are next parts to be splited:
1-30 - first part
2-134 - second part
6 - third part
0 - forth part
The frist, thirt and forth parts appears always. The second part appears sometimes.
The first part and second part can start from 1-XXX or 2-XXX.
The third part means number of products which are on stock.
The forth part is not important and can be ignored.

Table "Type"
id - value
1 - Product
2 - Color

Table "Arguments"
id - value
1 - sr20 h12
2 - sr21 h13
3 - blue
..
30 - sr25 h15
134 - red

Considering the above tables the early mentioned example would means:
1-30 would means 1=product, 30=sr25 h15
2-134 would means 2=color, 134=red

Could you please help me prepare php script which would properly display products in the way:
Product 1 - size: sr25 h15, color: red, on stock: 6
Product 1 - size: sr30 h16, color: blue, on stock: 13
Product 1 - size: sr35 h20, color: pink, on stock: 2
Product 2
Product 3 - color: white, on stock 4

############################

Thanks to Bill's suggestions I have splitted fileds by:
$products = explode(";;", $details);
foreach ...
$fields = explode(":", $products);
foreach ...
$attribs = explode(",", $fields);
foreach ...

However, I don't know how should I use:
($attrib_type, $attrib_value) = explode("-", $attribs[0]);

I have also prepared pre-loaded association table for arguments, but I don't know how can I use it.

This is my code:

$results = mysql_query("SELECT id, name, details FROM products")
or die ('query error');

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>";

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此岸叶落 2024-08-23 07:06:40

更新:我将对您的问题提供另一个答案,但我将在下面保留我的原始答复。

您需要使用像 explode() 这样的 PHP 函数来分隔您的“详细信息”字符串。例如,假设您已从数据库中获取行并且 $details 包含该字符串,您可以将其分成单独的产品,如下所示:

$products = explode(";;", $details);

然后您可以像这样分隔产品字段:

$fields = explode(":", $products[0]);

然后您可以分隔颜色、尺寸等属性如下:

$attribs = explode(",", $fields[0]);

然后您可以像这样获取颜色/尺寸的键:

($attrib_type, $attrib_value) = explode("-", $attribs[0]);

现在您可以使用 $attrib_type 表示“颜色”与“尺寸”。您可以使用 $attrib_valueArguments 表中查找。我建议通过主键将参数预加载到关联数组中,这样您就可以引用它们,而无需运行额外的 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 的外键是复合键。因此,它只能引用具有裤子产品类型的 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>

update: I'm going to offer another answer to your question, but I'll leave my original response included below.

You need to use a PHP function like explode() to separate the elements of your "details" string. For example, supposing you have fetched the row from the database and $details contains the string, you can separate it into individual products like this:

$products = explode(";;", $details);

Then you can separate the product fields like this:

$fields = explode(":", $products[0]);

Then you can separate the attributes like color, size, etc. like this:

$attribs = explode(",", $fields[0]);

Then you can get the key for color/size like this:

($attrib_type, $attrib_value) = explode("-", $attribs[0]);

Now you can use $attrib_type for "color" vs. "size". You can use $attrib_value to look up in the Arguments table. I would recommend pre-loading the arguments into an associative array by primary key, so you can just reference them without having to run extra SQL queries.

This really is much, much more work than you should have to do for this task.


You're sorely in need of database normalization. By using the design you show, you aren't taking advantage of the power your RDBMS could give you with respect to enforcing consistent, structured data.

First you need to create a table to record each type of products.

CREATE TABLE ProductTypes (
  product_id SERIAL PRIMARY KEY,
  description TEXT
);

INSERT INTO ProductTypes (product_id, description) VALUES
  (1234, 'Pants'), 
  (3456, 'Shirts');

Then you need a table for each SKU. This table records common product information such as quantity in stock, and price.

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

For each subtype of product, you also need a table to record attributes that are specific to the respective type. You might also need some lookup tables listing the permitted values for some of these attributes.

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');

Notice how the product_id in this table is limited by a CHECK constraint, and the foreign key to ProductSkus is a compound key. So it can only reference a SKU with the Pants product type. This way you don't accidentally create a row in Pants that references a Shirts SKU.

Now to display pants information in PHP, you can do something simple like this:

<?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>
老子叫无熙 2024-08-23 07:06:40

这是一个关于使用 php 分割描述的很棒的教程,但是如果字符串中包含 html 标签会发生什么。

这是处理这种情况的教程

http://phpschools .freehostia.com/other-stuff/split-html-description-in-php

It's a great tutorial for split description with php but what happen if string having html tags in it.

Here is a tutorial to work with that condition

http://phpschools.freehostia.com/other-stuff/split-html-description-in-php

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文