In deze blogpost ga ik het hebben over wat een recursieve functie is en wat je er mee kan. Als eerste gaan we kijken wat een recursieve functie is.
Recursie is het optreden van een constructie als onderdeel van zichzelf. Recursieve constructies worden veelvuldig gebruikt in de wiskunde, informatica en logica en in de (generatieve) taalkunde.
Een recursieve functie is dus een functie die zichzelf aanroept binnen de functie. Let op! Als je iets fout doet kan dit dus een oneindige loop veroorzaken! Er worden niet zo vaak recursieve functies gebruikt maar het is altijd handig om te weten hoe het werkt. In deze blogpost gaan we een functie schrijven waarmee we alle bestanden uit de opgegeven folder en onderliggende folders kunnen ophalen.
We beginnen zonder functie. Deze gaan we later bouwen, eerst wat meer uitleg over welke PHP methode we gaan gebruiken en hoe deze werkt.
Om bestanden op te halen gebruiken we de glob functie die standaard in php zit:
glob();
Door er een variabele aan toe te voegen geven we de juiste folder aan. vervolgens voegen we er nog een trailing slash aan toe en een asteriks omdat we alle bestanden en folders willen ophalen.
glob($dir.'/*');
Als we er vervolgens een foreach
loop van maken kunnen we door alle bestanden en folders heen loopen. Ook geven we de variabele $dir
een waarde.
$dir = "project";
foreach(glob($dir.'/*') as $filename) {
echo $filename . "/r/n";
}
Je krijgt nu alle folders en bestanden in de folder project
te zien. Echter krijg je niet alle bestanden in de folders in de map project
te zien. Om te kijken of een van de terug gegeven variable een folder is gebruiken we de php functie is_dir
.
$dir = "project";
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
// todo
}
echo $filename . "/r/n";
}
We weten nu dus welke variabele een folder zijn en welke niet. Om de bestanden daarin op te vragen zouden we natuurlijk nog een keer de bovenstaande code kunnen gebruiken. Echter hebben we dan weer hetzelfde probleem dat we wederom dezelfde code zouden moeten gebruiken. Aangezien de folder structuur niet bekend is en meerdere niveau’s diep kan zijn is dit niet een efficiente oplossing zoals hier onder te zien is.
$dir = "project";
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
// etc. etc.
}
echo $filename . "/r/n";
}
}
echo $filename . "/r/n";
}
}
echo $filename . "/r/n";
}
}
echo $filename . "/r/n";
}
Zoals je ziet is dit niet alleen erg onoverzichtelijk maar ook niet erg efficient om te onderhouden. Als we nu een aanpassing willen doen aan de code moeten we dezelfde aanpassing meerdere malen doen. Daarnaast kan het voorkomen dat de folder structuur dieper gaat dan de code die we hebben geschreven waardoor er bestanden kunnen missen. In plaats daarvan gaan we nu een functie maken van de bovenstaande code.
function get_files($dir) {
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
// todo
} else {
echo $filename . "/r/n";
}
}
}
Vervolgens willen we natuurlijk dat als de huidige variabele een directory is dat we opnieuw de functie aanroepen. Dus laten we bij de if(is_dir($filename))
opnieuw de functie uitvoeren.
function get_files($dir) {
foreach(glob($dir.'/*') as $filename) {
if (is_dir($filename) {
get_files($filename);
} else {
echo $filename . "/r/n";
}
}
}
Het enige wat er nu nog zou moeten gebeuren is het aanroepen van de functie zodat deze wordt gestart. Als je vervolgens de output zou bekijken krijg je alle bestanden te zien in de opgegeven folder en alle onderliggende folders.