Der zweite Aufruf kann übrigens schneller sein, weil das Betriebssystem - also nicht PHP - die Directory-Einträge zwischenspeichert. Womöglich könnte es also hilfreich sein, wenn Du ein anderes Dateisystem oder beim mounten andere Optionen benutzt, damit das OS mit vielen Einträgen in einem Verzeichnis besser zu recht kommt.
Falles wider Erwarten tatsächlich an is_file() liegen sollte:
der Backtick-Operator könnte Dir WOMÖGLICH helfen. Allerdings habe ich Zweifel. Am besten, Du misst mit den Unterschied selbst.
<?php
$dir=/foo/bar/';
$output = ls -al $dir
;
echo "<pre>$output</pre>";
?>
Splitte die Rückgaben erst zeilenweise - steht dann als erstes Zeichen ein '-' im String ist es eine normale Datei (und interessiert Dich), steht da ein "d" ist es ein Verzeichnis.
Splitte die Ausgaben danach an den(Plural!) Leerzeichen. Bitte beachte, das ls ein Befehl ist, der unterschiedlich implementiert sein kann. Mit der Vorgehensweise verlierst Du also die Unabhängigkeit vom Betriebssytem. Unter Windows wird das also schon mal nicht so gehen.