Il procedimento dovrebbe essere questo:

$i: è il contatore
$array[]: è l'array che contiene i tuoi dati

1) Conti quanti elementi ha $array[]
2) Dividi il risultato ottenuto per il numero di colonne che vuoi arrotondando per eccesso.
In pratica mettiamo che
$array[] = 21
e tu voglia 4 colonne

Fai:

$array[]/4 = 5,250000

Arrotondi per eccesso (il risultato è 6)

cominci a processare il tuo array

Ad ogni controllo sull'elemento fai in questo modo:

if ($i/$num_array == 0)
{
echo 'tag per chiudere la colonna ed aprirne una nuova';
}
In questo modo hai ottenuto le 4 colonne.

Ma c'è un problema:
Cosa succede se nell'ultima colonna non ci sono abbastanza elementi da far risultare $i/$num_array == 0?
Succede che l'ultima colonna non verrà chiusa.

Io ovvierei al problema in qesto modo
Stamperei a priori la chiusura dell'ultima colonna
Inserirei un altro contatore che mi faccia sapere a che colonna sto (viene incrementato quando stampi i tag di chiusura della colonna e apri quelli per la nuova colonna)
Quando arriva il momento di stampare i tag di apertura e chiusura controllo anche il contatore delle colonne: se è uguale al numero di colonne che vuoi ottenere allora non stampi niente.

Se non sono stato chiaro o non hai capito qualcosa posta che ti spiegomeglio.

Cmq forse ti risulterà più chiaro con uno pseudo codice:

codice:
$array[] = 21;
$cols = 4;

$num_array = $array[]/$cols; //5,250000
$num_array = arrotonda_per_eccesso($num_array); // 6

$icols = 0;
$iarray = 0;

echo 'apri tabella-apri colonna';
foreach (---------------)
       {
          fai quello che divi fare con l'array
          if ($iarray == $num_array)
            {
               if ($icols != $cols)
                 {
                    echo 'tag chiusura colonna-apertura colonna';
                    icols++;
                 }
               $iarray++;
            }
          
       }
echo 'chiudi tabella-chiudi colonna';
Così dovrebbe funzionare.
Fammi sapere! Ciao!