2017-04-30 2 views
2

Je tente de créer des groupes d'options pour un formulaire de sélection de liste déroulante, mais l'erreur suivante s'affiche sur la ligne $innerRow = mysqli_fetch_array($innerResults).Groupement d'options dans la liste déroulante des résultats MySQL

Attention: mysqli_fetch_array() attend le paramètre 1 à mysqli_result, booléen donné

code

$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) 
+0

Pouvez-vous 'imprimer $ query;' avant les instructions '$ outerResults =' et '$ innerResults ='? – Manngo

Répondre

0

Tout d'abord, la raison pour laquelle vos requêtes internes échouent est parce que vous n'avez pas emballé votre {$outerRow["manufacturer_name"]} entre guillemets simples comme valeurs de chaîne nécessitent et vous n'avez pas fermé la parenthèse de votre sous-requête: '{$outerRow["manufacturer_name"]}'); Mais je ne veux pas que vous corrigiez votre requête, s'il vous plaît continuez à lire ...

Il y a quelques petites choses que je voudrais corriger au sujet de votre processus:

  • Votre première requête n'utilise pas la vraie puissance de MySQL. Vous ne devriez pas créer de nouvelle requête pour chaque fabricant dans votre base de données - c'est inefficace.
  • Je vous recommande de déclarer et de vérifier l'état du jeu de résultats de votre requête pour éviter les messages d'AVERTISSEMENT et gérer correctement une requête erronée.
  • Vous ne fermez pas vos tags <optgroup> pendant votre construction dom. Votre sortie sera toujours rendue comme vous le souhaitez, mais les balises sont censées être fermées. Comme vous n'utilisez pas les touches numériques de vos résultats, vous devez utiliser mysqli_fetch_assoc() au lieu de mysqli_fetch_array().

Ceci est une réécriture complète de votre code, qui fera les corrections ci-dessus et d'affiner votre processus d'interrogation vers le bas à un seul appel:

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

J'ai testé le code ci-dessus en utilisant ces structures de table et les données :

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; 

ET

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; 

Mon bloc de code Affichera ceci:

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

Ce qui rend comme:

enter image description here

P.S. Si vous ne voulez pas les fabricants sans produit dans votre resultset (ou sélectionnez la liste d'options), écrivez HAVING P.product_id IS NOT NULL entre les lignes/clauses GROUP BY et ORDER BY.