Show products by category parameter in a more optimized way

0

Good evening! Well, I'll explain what I'm trying to do. I have here a table in my database that corresponds to the products and I have a page that shows these products. It turns out that one of the parameters of this table refers to the category of a particular product. What I need is to show the products by category me using this parameter. Each category must have an HTML Heading stating the name of the category before entering the products referring to it below. The detail is that I have already been able to do this, but in a somewhat "dirty" way. I'm using a variable to set the name of a certain category and then I'm establishing a database connection that compares the value of the variable with the value of the category of each product, and then inserts them below the HTML Heading corresponding to that category. The bad thing about this is that I have to manually create multiple connections according to the number of categories present, and I think there is a better way to do that. I think everything will become clearer with the code. >

$categoria_produto = "Comidas";

$sql = "SELECT id_produto, nome_produto, preco_produto, categoria_produto FROM produtos WHERE categoria_produto LIKE '{$categoria_produto}' ORDER BY nome_produto";
$stmt = $conexao->prepare($sql);
$stmt->execute();

$num = $stmt->rowCount();

if($num>0)
{
    echo "<h1>{$categoria_produto}</h1>";
        echo "<table>";
        echo "  <tr>";
        echo "      <th>NOME</th>";
        echo "      <th>PREÇO</th>";
        echo "      <th>QUANTIDADE</th>";
        echo "  </tr>";
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    {
        extract($row);
        $preco_produto_reajustado = number_format($preco_produto, 2, ",", ".");
        echo "  <tr>";
        echo "      <td><div class='id-produto' style='display: none'>{$id_produto}</div>";
        echo "      <div class='nome-produto'>{$nome_produto}</div></td>";
        echo "      <td>R&#36;{$preco_produto_reajustado}</td>";
        echo "      <td>";
        echo "          <form class='adicionar'>";
        echo "          <input type='number' name='quantidade' value='1' min='1' max='20'/>";
        echo "          <button type='submit'>Adicionar</button>";
        echo "          </form>";
        echo "      </td>";
        echo "  </tr>";
    }
        echo "</table>";
}
else
{
    echo "Sem produtos na categoria {$categoria_produto}.<br/>";
}

See why I'm not liking this method. All of the above code only concerns the Comidas category! For example, if I want products for the Eletrônicos category to be shown too, I'll have to use it below:

$categoria_produto = "Eletrônicos";

$sql = "SELECT id_produto, nome_produto, preco_produto, categoria_produto FROM produtos WHERE categoria_produto LIKE '{$categoria_produto}' ORDER BY nome_produto";
$stmt = $conexao->prepare($sql);
$stmt->execute();

$num = $stmt->rowCount();

if($num>0)
{
    echo "<h1>{$categoria_produto}</h1>";
        echo "<table>";
        echo "  <tr>";
        echo "      <th>NOME</th>";
        echo "      <th>PREÇO</th>";
        echo "      <th>QUANTIDADE</th>";
        echo "  </tr>";
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    {
        extract($row);
        $preco_produto_reajustado = number_format($preco_produto, 2, ",", ".");
        echo "  <tr>";
        echo "      <td><div class='id-produto' style='display: none'>{$id_produto}</div>";
        echo "      <div class='nome-produto'>{$nome_produto}</div></td>";
        echo "      <td>R&#36;{$preco_produto_reajustado}</td>";
        echo "      <td>";
        echo "          <form class='adicionar'>";
        echo "          <input type='number' name='quantidade' value='1' min='1' max='20'/>";
        echo "          <button type='submit'>Adicionar</button>";
        echo "          </form>";
        echo "      </td>";
        echo "  </tr>";
    }
        echo "</table>";
}
else
{
    echo "Sem produtos na categoria {$categoria_produto}.<br/>";
}

The output is being desired, but the code is not appealing to me.
As I said earlier, I am not finding it feasible to solve this problem in this way, I believe there is a better way of doing what I am intending. Thanks in advance for any help!

    
asked by anonymous 05.04.2015 / 23:33

1 answer

1

As each one has its way of programming, let's emphasize your query, the way I think it is most correct would be to create a categoria table and then create a foreing key in the produto table, / p>

[PRODUTO]
id_produto
nome_produto
preco_produto
id_categoria

[CATEGORIA]
id_categoria
descricao

In this way, you would make an appointment like this:

SELECT 
  p.id_produto,
  p.nome_produto,
  p.preco_produto,
  p.id_categoria,
  c.descricao 
FROM
  produtos p, categoria c 
WHERE c.id_categoria = p.id_categoria 
ORDER BY p.id_categoria,
  p.nome_produto

So far we have organized your structure so that it optimizes the search and storage of the data, so you do not need to record a category name several times, but rather to relate the product to the corresponding id.

Now let's go to the code, instead of making multiple selects per category, make a query only by organizing first by category and then by product name, printing everything in the same loop, thus:

//Editado devido a um pequeno erro de sintaxe
$sql = "SELECT p.id_produto, p.nome_produto, p.preco_produto, p.id_categoria, c.descricao FROM produtos p, categoria c WHERE c.id_categoria = p.id_categoria ORDER BY p.id_categoria, p.nome_produto";
$stmt = $conexao->prepare($sql);
$stmt->execute();

$num = $stmt->rowCount();
$categoria = null;
if($num>0) {
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        extract($row);
        if($categoria != $id_categoria) {
            if(!is_null($categoria)) { echo "</table>"; } // Fechando a tabela da ultima categoria impressa antes de abrir a nova

            echo "<h1>{$descricao}</h1>";
            echo "<table>";
            echo "  <tr>";
            echo "      <th>NOME</th>";
            echo "      <th>PREÇO</th>";
            echo "      <th>QUANTIDADE</th>";
            echo "  </tr>";

            $categoria = $id_categoria;
        }

        $preco_produto_reajustado = number_format($preco_produto, 2, ",", ".");
        echo "  <tr>";
        echo "      <td><div class='id-produto' style='display: none'>{$id_produto}</div>";
        echo "      <div class='nome-produto'>{$nome_produto}</div></td>";
        echo "      <td>R&#36;{$preco_produto_reajustado}</td>";
        echo "      <td>";
        echo "          <form class='adicionar'>";
        echo "          <input type='number' name='quantidade' value='1' min='1' max='20'/>";
        echo "          <button type='submit'>Adicionar</button>";
        echo "          </form>";
        echo "      </td>";
        echo "  </tr>";
    }
    echo "</table>"; // Fechando a tabela da última categoria do laço

}

If you do not want to change your bank structure as suggested, you can do the same loop, however, by treating the category description instead of the id as I did.

Of course there are several ways, this is one of them, I hope it helps.

Embrace

    
06.04.2015 / 00:25