Before answering I need to warn you, your Theads are being generated on the same level as the other Trs that do not belong to the Theads themselves, there should be a TBODY in each, but the main problem is that you have put everything inside TBODY, but it is likely that the renderer "correct".
Your problem goes beyond adding a line, it has to add up the values, keeping this in mind it is necessary 2 auxiliary variables, a kind you have already made $categoriaAtual = null;
, but the sum of.
Another thing, if you are going to mix so much HTML with PHP I would personally choose to use this format:
<?php if (): ?>
html
<?php endif; ?>
and
<?php for/while/foreach (): ?>
<?php endfor/endwhile/endforeach; ?>
There is no gain in performance, the question just improve a little as you see the code, overall it should look like this:
<?php
$produtos = array(
array('cod' => 8, 'nome' => 'Produto teste 8', 'grupo' => 'Doces', 'valor' => 1007),
array('cod' => 9, 'nome' => 'Produto teste 9', 'grupo' => 'Doces', 'valor' => 1050),
array('cod' => 10, 'nome' => 'Produto teste 10', 'grupo' => 'Doces', 'valor' => 1050),
array('cod' => 1, 'nome' => 'Produto teste 1', 'grupo' => 'Farinha', 'valor' => 1400),
array('cod' => 2, 'nome' => 'Produto teste 2', 'grupo' => 'Farinha', 'valor' => 170),
array('cod' => 4, 'nome' => 'Produto teste 4', 'grupo' => 'Frios', 'valor' => 1600),
array('cod' => 5, 'nome' => 'Produto teste 5', 'grupo' => 'Frios', 'valor' => 1800),
array('cod' => 6, 'nome' => 'Produto teste 6', 'grupo' => 'Frios', 'valor' => 1070),
array('cod' => 7, 'nome' => 'Produto teste 7', 'grupo' => 'Frios', 'valor' => 1070),
array('cod' => 11, 'nome' => 'Produto teste 11', 'grupo' => 'Frios', 'valor' => 1060),
array('cod' => 3, 'nome' => 'Produto teste 3', 'grupo' => 'Limpeza', 'valor' => 1080)
);
?>
<table>
<?php
// Inicía variável
$categoriaAtual = null;
$categoriaTotal = 0;
?>
<?php foreach ($produtos as $produto): ?>
<?php if ($categoriaAtual !== $produto['grupo']): ?>
<?php
// Entra neste IF se não for o primeiro produto, devido ao NULL inicial
if ($categoriaAtual !== null):
?>
<tr>
<td colspan="2">Total</td>
<td><?=$categoriaTotal?></td>
</tr>
<?php
// Quando muda de categoria é necessário "resetar" a soma para poder começar novamente
$categoriaTotal = 0;
?>
</tbody>
<?php endif; ?>
<thead>
<tr>
<td colspan="100%">
<b><i><?=$produto['grupo']?></i><b>
</td>
</tr>
<tr>
<td>Cód. Produto</td>
<td>Produto</td>
<td>Valor</td>
</tr>
</thead>
<?php endif; ?>
<?php
//Seta o valor sempre, para o proximo ciclo poder saber se o grupo mudou
$categoriaAtual = $produto['grupo'];
//Soma os valores a cada ciclo
$categoriaTotal += $produto['valor'];
?>
<tr>
<td><?= $produto['cod'] ?></td>
<td><?= $produto['nome'] ?></td>
<td><?= $produto['valor'] ?></td>
</tr>
<?php endforeach; ?>
<?php
//Nesta parte o foreach já terminou, mas é necessário pegar o total
//do ultimo grpo e fechar o TBODY e isto só pode ocorrer se tiver ao
//menos um produto no array, se tiver zero nem entra neste IF
if ($categoriaAtual !== null):
?>
<tr>
<td colspan="2">Total</td>
<td><?=$categoriaTotal?></td>
</tr>
</tbody>
<?php endif; ?>
</table>
To see the result put in Stacksnipet below:
table {
width: 100%;
}
td {
border: 1px solid #ccc;
}
thead {
background: #00f;
color: #fff;
}
<table>
<thead>
<tr>
<td colspan="100%">
<b><i>Doces</i><b>
</td>
</tr>
<tr>
<td>Cód. Produto</td>
<td>Produto</td>
<td>Valor</td>
</tr>
</thead>
<tr>
<td>8</td>
<td>Produto teste 8</td>
<td>1007</td>
</tr>
<tr>
<td>9</td>
<td>Produto teste 9</td>
<td>1050</td>
</tr>
<tr>
<td>10</td>
<td>Produto teste 10</td>
<td>1050</td>
</tr>
<tr>
<td colspan="2">Total</td>
<td>3107</td>
</tr>
</tbody>
<thead>
<tr>
<td colspan="100%">
<b><i>Farinha</i><b>
</td>
</tr>
<tr>
<td>Cód. Produto</td>
<td>Produto</td>
<td>Valor</td>
</tr>
</thead>
<tr>
<td>1</td>
<td>Produto teste 1</td>
<td>1400</td>
</tr>
<tr>
<td>2</td>
<td>Produto teste 2</td>
<td>170</td>
</tr>
<tr>
<td colspan="2">Total</td>
<td>1570</td>
</tr>
</tbody>
<thead>
<tr>
<td colspan="100%">
<b><i>Frios</i><b>
</td>
</tr>
<tr>
<td>Cód. Produto</td>
<td>Produto</td>
<td>Valor</td>
</tr>
</thead>
<tr>
<td>4</td>
<td>Produto teste 4</td>
<td>1600</td>
</tr>
<tr>
<td>5</td>
<td>Produto teste 5</td>
<td>1800</td>
</tr>
<tr>
<td>6</td>
<td>Produto teste 6</td>
<td>1070</td>
</tr>
<tr>
<td>7</td>
<td>Produto teste 7</td>
<td>1070</td>
</tr>
<tr>
<td>11</td>
<td>Produto teste 11</td>
<td>1060</td>
</tr>
<tr>
<td colspan="2">Total</td>
<td>6600</td>
</tr>
</tbody>
<thead>
<tr>
<td colspan="100%">
<b><i>Limpeza</i><b>
</td>
</tr>
<tr>
<td>Cód. Produto</td>
<td>Produto</td>
<td>Valor</td>
</tr>
</thead>
<tr>
<td>3</td>
<td>Produto teste 3</td>
<td>1080</td>
</tr>
<tr>
<td colspan="2">Total</td>
<td>1080</td>
</tr>
</tbody>
</table>
Answer before editing
If you know how many items an array/iterator has, then you know when the last one will actually be, even before the foreach
you and the "script" already know when should be the last, just increment a variable from scratch like this:
<?php
$funcionarios = array(
array('id' => 1, 'nome' => 'João', 'salario' => 5000),
array('id' => 22, 'nome' => 'Mauro', 'salario' => 560),
array('id' => 8, 'nome' => 'Alice', 'salario' => 4300),
);
$j = count($funcionarios);
for ($i = 0; $i < $j; ++$i) {
if ($j - 1 === $i) {
//Aqui vai a tal linha sobre o ultimo resultado
}
$funcionario = $funcionarios[$i];
echo $funcionario["nome"]." $".$funcionario["salario"]."<br>\n";
// Aqui quero colocar o proximo resultado
}
Now if the data came from a bank, then I suppose you used fetchAll
of PDO
supports Count and in foreach with PDO can apply within the scope a ++$i
If mysqli API can use num_rows()
(or SELECT FOUND_ROWS();
in a query, depending on what you did) before iterating.
And what would be the need for this? If the need is what I imagine then the strategy would be 2 loops, but I can’t say without details, the good thing about explaining this in the question is that sometimes you think you need something that you don’t really need and so we can give better suggestions that address your problem.
– Guilherme Nascimento
I edited the question in more detail
– Hugo Borges
You could do the
foreach
withas $i => $functionario
and display the salary of$functionarios[$i+1]
, with the appropriate conditions, but also did not understand very well the objective, mainly in relation to the product group being the example with employees.– Woss
Could you give a real example? I believe two people answered the question without clarifying your question. Since you speak in grouped products (therefore I understand that there are multiple groups), but your code treats a list of employees without grouping...
– bfavaretto
@bfavaretto de fata is true, I edited the question with a real example
– Hugo Borges
If it is the total, then simply iterate will not solve fully, has to add, but can do in a single is, I will try to do here and put in the answer
– Guilherme Nascimento
I will withdraw the answer for now because I have no way to analyze at the moment. When you are more relaxed I give a feedback.
– Augusto Vasques
Hugo e @Augustovasques editei https://answall.com/a/435115/3635, simplified for an IF, the important part, which is now evident, was the sum of the values, had problems in HTML markup, I made some adjustments, about semantics I do not know if it is OK, but the logic without needing 2 "for"s gave to adjust, I will comment on the code to be clearer.
– Guilherme Nascimento