El asunto es que no debes forzar las etiquetas <ul><li> con lógica fuera de la función, la única cosa que es consistente es que una lista de elementos siempre regresará la misma estructura.
Código PHP:
Ver originalfunction re($list) {
$html = [];
// apretura, siempre
$html []= '<ul>';
// items
foreach ($list as $item) {
// lógica para recursividad (lista anidada)
$html []= '<li>' . re($item) . '</li>';
} else {
// sólo un item más
$html []= '<li>' . $item . '</li>';
}
}
// cierre, siempre
$html []= '</ul>';
// es mejor un return que un echo
return join("\n", $html); }
echo re([1, 2, [5, 6, [7, 8]], 3, 4]);