Was Alexander meint, ist folgendes:
Du öffnest zuerst mit $DBO->query("SELECT DirectoriesID,Level
[..] ein Result-Set.
Anschließend wird für jede Zeile die Funktion hasChildKats() aufgerufen.
In dieser Funktion wird mit $DBO->query("SELECT DirectoriesID FROM
[...] erneut ein Result-Set geöffnet. Und weil gleichzeitig noch das erste Result-Set geöffnet ist, funktioniert das ohne MARS nicht.
Die Lösung mit den parallelen Verbindungen würde so funktionieren, dass du in der Funktion hasChildKats() eine neue Connection aufbaust, wodurch sich die beiden Queries nicht in die Quere kommen.
Übrigens könntest du in deinem Beispiel eine Abfrage (mehr oder weniger) vermeiden, nämlich über eine Unterabfrage:
SELECT
DirectoriesID,
Level,
(SELECT COUNT(subdirectories.DirectoriesID) FROM directories AS subdirectories WHERE subdirectories.ParentID = directories.DirectoriesID) AS NumSubDirectories
FROM
directories
WHERE
ParentID = '$parentid'
ORDER BY
DirectoriesID
In NumSubDirectories steckt dann jeweils die Anzahl der Unterordner der aktuellen Zeile.