从MySQL结果下拉选项分组

时间:2017-04-30 21:39:11

标签: php mysqli drop-down-menu html-select optgroup

我正在尝试为下拉列表选择表单创建选项组,但我在$innerRow = mysqli_fetch_array($innerResults)行收到以下错误。

  

警告:mysqli_fetch_array()期望参数1为mysqli_result,   给定布尔值

代码

$options = "";
$query = "SELECT DISTINCT manufacturer_name 
          FROM product p 
          JOIN manufacturer m 
          ON p.manufacturer_id = m.manufacturer_id";
$outerResults = mysqli_query($con, $query);
while ($outerRow = mysqli_fetch_array($outerResults)) {
    $options .= "<optgroup label='{$outerRow["manufacturer_name"]}'>";

    $query = "SELECT product_id, model_number
              FROM product
              WHERE manufacturer_id 
              IN (SELECT manufacturer_id 
              FROM manufacturer 
              WHERE manufacturer_name = {$outerRow["manufacturer_name"]}";
    $innerResults = mysqli_query($con, $query);
    while ($innerRow = mysqli_fetch_array($innerResults)) {
        $options .= "<option value='{$innerRow["product_id"]}'>{$innerRow["model_number"]}</option>";
    }
    mysqli_free_result($innerOptions);
}
mysqli_free_result($outerOptions);
mysqli_close($con)

1 个答案:

答案 0 :(得分:0)

首先,您的内部查询失败的原因是您没有将{$outerRow["manufacturer_name"]}用单引号括起来,因为字符串值需要并且您没有关闭子查询的括号:'{$outerRow["manufacturer_name"]}');但我不知道我想让你解决问题,请继续阅读...

我想就您的流程纠正一些事项:

  • 您的第一个查询未使用MySQL的真正威力。你真的不应该为你的数据库中的每个制造商做一个新的查询 - 这是低效的。
  • 我建议您声明并条件检查查询的结果集,以避免出现WARNING消息并正确处理错误查询。
  • 在dom版本中,您没有关闭<optgroup>代码。您的输出仍将根据需要进行渲染,但标记应关闭。
  • 由于您未使用结果集中的数字键,因此您应使用mysqli_fetch_assoc()代替mysqli_fetch_array()

这是对您的代码的完全重写,它将进行上述更正并将您的查询过程简化为一次调用:

require_once("db.php");
$sql="SELECT M.manufacturer_name,P.product_id,P.model_number 
      FROM manufacturer M 
      LEFT JOIN product P ON M.manufacturer_id=P.manufacturer_id 
      GROUP BY M.manufacturer_id,P.product_id
      ORDER BY M.manufacturer_name,P.model_number;";    
if($result=mysqli_query($con,$sql)){
    if(mysqli_num_rows($result)){
        $last_group=null;
        $select="<select name=\"products\">";
            while($row=mysqli_fetch_assoc($result)){
                if($row["manufacturer_name"]!=$last_group){
                    $select.=($last_group!=null?"</optgroup>":"")."<optgroup label=\"{$row["manufacturer_name"]}\">";
                    $last_group=$row["manufacturer_name"];
                }
                if($row["product_id"]==null){
                    $select.="<option disabled>No Products</option>";
                }else{
                    $select.="<option value=\"{$row["product_id"]}\">{$row["model_number"]}</option>";
                }
            }
        $select.="</optgroup></select>";
        echo $select;
        mysqli_free_result($result);
    }else{
        echo "Empty Resultset From Query";  
    }
}else{
    echo mysqli_error($con);    
}

我使用这些表结构和数据测试了上面的代码:

CREATE TABLE `product` (
  `product_id` int(10) NOT NULL,
  `manufacturer_id` varchar(20) NOT NULL,
  `model_number` varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `product` (`product_id`, `manufacturer_id`, `model_number`) VALUES
(1, '1', '#0001'),
(2, '1', '#0002'),
(3, '1', '#0003'),
(4, '2', '#0001'),
(5, '2', '#0002'),
(6, '4', '#0001');

ALTER TABLE `product`
  ADD PRIMARY KEY (`product_id`);

ALTER TABLE `product`
  MODIFY `product_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;

CREATE TABLE `manufacturer` (
  `manufacturer_id` int(10) NOT NULL,
  `manufacturer_name` varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `manufacturer` (`manufacturer_id`, `manufacturer_name`) VALUES
(1, 'AAAA'),
(2, 'BBBB'),
(3, 'CCCC'),
(4, 'DDDD');

ALTER TABLE `manufacturer`
  ADD PRIMARY KEY (`manufacturer_id`);

ALTER TABLE `manufacturer`
  MODIFY `manufacturer_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

我的代码块将输出:

<select name="products">
    <optgroup label="AAAA">
        <option value="1">#0001</option>
        <option value="2">#0002</option>
        <option value="3">#0003</option>
    </optgroup>
    <optgroup label="BBBB">
        <option value="4">#0001</option>
        <option value="5">#0002</option>
    </optgroup>
    <optgroup label="CCCC">
        <option disabled>No Products</option>
    </optgroup>
    <optgroup label="DDDD">
        <option value="6">#0001</option>
    </optgroup>
</select>

呈现为:

enter image description here

P.S。如果您不希望在结果集中使用无产品制造商(或选择选项列表),请在HAVING P.product_id IS NOT NULLGROUP BY行/子句之间写下ORDER BY