It is important to remember that in a form submission only the <checkbox>
that are marked / selected are sent, which are not even sent. If this key is not marked, nor will it exist in $_POST['produtos']
, then this:
foreach($prod_comp as $value){
echo '<p align="center">'.$value."</p>";
}
foreach($qtd_prod as $value){
echo '<p align="center">'.$value."</p>";
}
foreach($precos as $key => $value){
echo '<p align="center">'.$value."</p>";
}
It is not correct because it assumes that all exist always and $prod_comp
will not always exist and will have size dependent on what was selected. In addition, $qtd_prod
and $precos
do not depend on what was chosen in $prod_comp
.
Instead we can change the html of <checkbox>
to have a sequential numeric value:
$prod['Margarina']=4.89;
$num = 0; //numero do produto
foreach($prod as $key => $value){
?>
<tr>
<td><input type="checkbox" name="produtos[]" value="<?=$num++?>"><?php echo $key; ?></td>
...
<?php
}
What will make the html generated for <checkbox>
look like this:
<td><input type="checkbox" name="produtos[]" value="0">Arroz</td>
<td><input type="checkbox" name="produtos[]" value="1">Macarrão</td>
<td><input type="checkbox" name="produtos[]" value="2">Biscoito Cream</td>
<td><input type="checkbox" name="produtos[]" value="3">Margarina</td>
In this way when submitted, by value
we know which lines we need to read to other arrays. We can then interpret as follows:
if ($_SERVER["REQUEST_METHOD"] == "POST"){ //se foi submetido em post
if (isset($_POST["produtos"])){ //se existem produtos escolhidos
//criar os nomes num array
$nomesProdutos = array('Arroz','Macarrão','Biscoito Cream','Margarina');
//obter todos os arrays que vem de $_POST como já era feito
$prod_comp = $_POST['produtos'];
$qtd_prod = $_POST['qtd'];
$precos = $_POST['preco'];
echo "Produtos escolhidos:";
//for apenas sobre os que foram escolhidos
for ($i = 0; $i < count($prod_comp);++$i){
$pos = $prod_comp[$i]; //obter a posição do elemento escolhido (0,1,2 ...)
//ir buscar as informações aos outros arrays com base nessa posição
echo "Nome: $nomesProdutos[$pos] Quantidade: $qtd_prod[$pos] Preço: $precos[$pos]<br>";
}
}
else {
echo "Não escolheu nenhum produto";
}
}
This solution already works for the intended purpose. A more organized solution would be to use classes because we have 3 distinct arrays that refer to the same thing, a product. For this reason we could create a Produto
class and create objects of that class within for
:
class Produto{
var $nome;
var $quantidade;
var $preco;
//construtor de Produto que recebe nome, quantidade e preço
function __construct($nome, $quantidade, $preco){
$this->nome = $nome;
$this->quantidade = $quantidade;
$this->preco = $preco;
}
}
if ($_SERVER["REQUEST_METHOD"] == "POST"){
if (isset($_POST["produtos"])){
$nomesProdutos = array('Arroz','Macarrão','Biscoito Cream','Margarina');
$prod_comp = $_POST['produtos'];
$qtd_prod = $_POST['qtd'];
$precos = $_POST['preco'];
echo "Produtos escolhidos:";
//Array de objetos produto
$produtos = array();
for ($i = 0; $i < count($prod_comp);++$i){
$pos = $prod_comp[$i];
//acrescentar um novo objeto produto ao array
$produtos[] = new Produto($nomesProdutos[$pos], $qtd_prod[$pos], $precos[$pos]);
}
//mostrar todos
print_r($produtos);
}
else {
echo "Não escolheu nenhum produto";
}
}
It would however make sense to create a specific method to be able to show Produto
in html in a more beautiful and organized way, so that the visualization would be identical to the classless code. This method might look like this:
class Produto{
...
//método para obter o html do produto de forma mais organizada
function obterHtml(){
return "Nome: {$this->nome} Quantidade: {$this->quantidade} Preço: {$this->preco}<br>";
}
}
And now we show you where you need to by just calling the method:
//mostrar todos
foreach ($produtos as $prod){
echo ($prod->obterHtml());
}
As an additional note, there is a small flaw in html that has a closing tag </td>
missing in:
<td><input type="number" name="qtd[]" id="qtd" min="0" max="100">
</tr>
That should be fixed for
<td><input type="number" name="qtd[]" id="qtd" min="0" max="100"></td>
</tr>