Puede mantener algún estado durante la iteración que realiza un seguimiento de si la fila actual es un nuevo nombre/a pagar:
$last_name_seen = NULL;
while ($row = mysql_fetch_array($result)) {
$firstname = "";
$payable = "";
if ($last_name_seen === NULL || $row['firstname'] != $last_name_seen) {
$last_name_seen = $row['firstname'];
$firstname = $row['firstname'];
$payable = $row['payable'];
}
echo '<tr>';
echo '<td style="border: 1px solid black;">'.$firstname.'</td>';
echo '<td>'.$payable.'</td>';
echo '<td>'.$row['product'].'</td>';
echo '<td>'.$row['qty'].'</td>';
echo '</tr>';
}
Tenga en cuenta que su consulta MySQL debe tener algo de ORDER BY
cláusula, para generar el pedido que desee, por ejemplo,
ORDER BY Name, Product;
Como también sugieren los comentarios anteriores, si está utilizando una API de PHP en desuso, debería considerar actualizar a algo más moderno. Pero, la lógica utilizada en el ciclo anterior no cambiaría mucho al cambiar la API de MySQL.