【问题标题】:Split Strings and arrange db to display products in PHP拆分字符串并安排数据库以在 PHP 中显示产品
【发布时间】:2009-12-27 04:21:19
【问题描述】:

我是 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 中的一行中,尽管产品还根据尺寸和颜色单独识别。这就是为什么有些产品的尺寸和颜色比其他产品多的原因。 有时产品只有一种尺寸,但有一些颜色。在这种情况下,这一种尺寸不存储在 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

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

感谢比尔的建议,我将文件拆分为:
$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") 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>";

}

【问题讨论】:

    标签: split tokenize


    【解决方案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_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 的外键是一个复合键。因此它可以引用具有 Pants 产品类型的 SKU。这样您就不会意外在 Pants 中创建引用 Shirts 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>
    

    【讨论】:

    • 亲爱的比尔,感谢您的及时回复。我忘了提到我不是数据库开发人员,我无法更改表内的任何内容。我只能基于现状。我需要找到一种方法来显示已按照我描述的方式放置在 db 中的产品。我可以理解,它可以再次归一化和其他标准。你知道如何做到这一点吗?
    【解决方案2】:

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

    这是处理该条件的教程

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多