


Erholungsergebnisse der Rekursivfunktion von PHP: Erstellen eines Dateisystemscanners
Einführung: Die Herausforderung der Rekursion und der Ergebnissammlung
Rekursion ist eine leistungsstarke Programmierungstechnik, mit der Funktionen Probleme lösen können, indem sie sich selbst anrufen, insbesondere für die Verarbeitung von Daten mit selbstähnlichen Strukturen wie Baumstrukturen oder Dateisystemen. Das Sammeln und Aggregieren von Ergebnissen zu rekursiven Aufrufen stößt jedoch häufig vor Herausforderungen. Wenn Daten in mehreren rekursiven Ebenen akkumuliert werden müssen, ist die Gewährleistung der korrekten Übergabe der Ergebnisse aller Sub-Abrechnungen ein zentrales Problem für Entwickler.
Häufige Fehleranalyse: Warum ist es ungültig, Arrays direkt zu übergeben?
Viele Anfänger stoßen auf ein häufiges Problem, wenn Sie versuchen, Daten aus rekursiven Funktionen zu sammeln: Übergeben Sie ein Array als Argument an die rekursive Funktion und erwarten Sie, dass sie in der Funktion geändert werden, um Daten in allen rekursiven Ebenen zu akkumulieren.
Betrachten Sie den folgenden Code -Snippet (basierend auf der ursprünglichen Frage):
Funktion Readdirs ($ path, $ result = []) // $ result wird standardmäßig von Wert übergeben { $ dirhandle = opendir ($ path); while ($ item = readdir ($ dirhandle)) { $ newpath = $ path. "/". $ item; if (is_dir ($ newpath) && $ item! = '.' && $ item! = '..')) { Readdirs ($ newpath, $ result); // rekursiv anrufen und eine Kopie von $ result} übergeben elseif (! is_dir ($ newpath) && $ item! = '.ds_store' && $ item! = '.' && $ item! = '..') { // echo "$ path <br>"; // Drucken Sie den aktuellen Verzeichnispfad $ result [] = $ path; // Die $ -sergebniskopie der aktuellen Funktion return $ $ result; // Rückgabe unterbrochen den Scan des aktuellen Verzeichnisses und unterbricht die Erwartung des Elternteils an das Ergebnis} } // Wenn keine Datei vorhanden ist oder die Datei im aktuellen Verzeichnis verarbeitet wird, wird implizit NULL oder leeres $ -Ergebnis zurückgegeben }
Problemanalyse:
- Nach Wert bestehen : In PHP werden die Funktionsparameter standardmäßig an Wert übergeben. Dies bedeutet, dass bei Readdirs ($ Newpath, $ -Ergebnis) eine Kopie des $ -Re -Ergebnis -Arrays an die Unterfunktion übergeben wird. Alle Änderungen an der $ -sergebnis -Kopie durch die untergeordnete Funktion wirken sich nicht auf das ursprüngliche $ -sergebnis -Array in der übergeordneten Funktion aus. Daher kann das Ergebnis nicht zwischen rekursiven Aufrufen akkumuliert werden.
- Frühgeborene Rendite : Das Ergebnis $ $ result; Die Anweisung im ElseIF -Block führt dazu, dass die Funktion unmittelbar nach dem Finden der ersten Datei und dem Hinzufügen des Verzeichnispfads zu $ Ergebnis beendet. Dies verhindert nicht nur das Scannen anderer Dateien und Unterverzeichnisse im aktuellen Verzeichnis, sondern macht es dem übergeordneten Aufruf auch unmöglich, weiterhin Daten zu sammeln.
Lösungskern: Aggregate Ergebnisse unter Verwendung von Funktionsrückgabewerten
Der Schlüssel zur Lösung des oben genannten Problems besteht darin, die Denkweise zu ändern: Die rekursive Funktion sollte sich nicht darauf verlassen, die übergebenen Array -Parameter zu ändern, um die Ergebnisse zu sammeln, sondern die auf aktuellen Ebene gesammelten Ergebnisse zurückgeben . Der übergeordnete Anrufer ist dafür verantwortlich, die vom Kind zurückgegebenen Ergebnisse zu erhalten und sie in seine eigene Ergebnismenge zu verschmelzen.
Dieser Ansatz stellt sicher, dass jeder Funktionsaufruf klare Verantwortlichkeiten hat: Verarbeitung der Daten auf der aktuellen Ebene und Rückgabe eines vollständigen Datensatzes mit den Ergebnissen der aktuellen Ebene und aller Aggregate von Unterebenen.
Erstellen Sie einen effizienten Dateipfadsammler
Hier ist ein optimiertes Beispiel für die Rekursivfunktion, das zum Scannen eines angegebenen Verzeichnisses und aller Subverhandlungen scannt und ein abgeflachtes Array zurückgibt, das die vollständigen Pfade aller Dateien (Nicht-Verzeichnis) enthält.
Php /** * Scannen Sie das angegebene Verzeichnis und seine Unterverzeichnisse rekursiv, um den vollständigen Pfad zu allen Dateien zu sammeln. * * @param String $ path Der Pfad zum Scannen des Startverzeichnisses. * @Return Array mit den vollständigen Pfaden aller Dateien. */ Funktion getAllFilepathsRecursive (String $ Path): Array { $ allFilepaths = []; // Initialisieren Sie das Ergebnisarray der aktuellen Ebene // Überprüfen Sie, ob der Pfad gültig ist, und ist ein öffentliches Verzeichnis, wenn (! Is_dir ($ path) ||! ($ Dirhandle = opendir ($ path)) { // Der Pfad ist ungültig oder das Verzeichnis kann nicht geöffnet werden, wodurch das leere Array error_log zurückgibt ("Verzeichnis kann nicht geöffnet werden:". $ Path); Return $ allFilepaths; } while (false! == ($ item = readdir ($ dirhandle))) { // Überspringen Sie das aktuelle Verzeichnis '.' und das vorherige Verzeichnis '..' if ($ item === '.' || $ item === '..') { weitermachen; } // Erstellen Sie einen vollständigen neuen Pfad mit dem plattformübergreifenden Verzeichnistrenntrenner $ newpath = $ path. Directory_separator. $ item; if (is_dir ($ newpath)) { // Wenn es sich um ein Verzeichnis handelt, rufen Sie sich selbst rekursiv an und kombinieren Sie das zurückgegebene Ergebnis mit der aktuellen Ergebnisnummer, und // Array_Merge wird verwendet, um das Array zu verflachten, um zu vermeiden, dass $ allFilepaths = array_merge ($ allFilepaths, getAllFilepathsRecursive ($ Newpath)); } anders { // Wenn es sich um eine Datei handelt, fügen Sie ihren vollständigen Pfad dem Ergebnisarray hinzu // Andere Dateifilterbedingungen können nach Bedarf hinzugefügt werden, z. B. ausschließend .ds_store if ($ item! } } } Closedir ($ dirhandle); // Schließen Sie das Verzeichnishandle und veröffentlichen Sie die Ressourcenrückgabe $ allFilepaths. // alle auf der aktuellen Ebene gesammelten Dateipfade zurückgeben} // Beispiel Verwendung: $ basepath = "/user/myComputer/dokuments/www/photos_projets"; // Bitte ersetzen Sie es durch Ihren tatsächlichen Pfad // Überprüfen Sie, ob der Startpfad existiert, und ist ein Verzeichnis, wenn (! Is_dir ($ basepath)) { Echo "Fehler: Der Startpfad existiert nicht oder ist kein Verzeichnis. \ n"; } anders { $ sammelfilepaths = getAllFilepathsrecursive ($ Basepath); echo "--- der gesammelte Dateipfad --- \ n"; if (leer ($ sammelfilepaths)) { echo "Keine Dateien gefunden. \ n"; } anders { foreach ($ sammelfilepaths als $ filepath) { Echo $ filepath. "\N"; } echo "insgesamt gesammelt". count ($ sammelfilepaths). "Dateien. \ n"; } // Sie können auch var_dump ($ sammelfilepaths) verwenden; um die Array -Struktur anzuzeigen} ?>
Code Parsen:
- $ allFilepaths = []; : Initialisieren Sie ein lokales leeres Array am Anfang jedes Funktionsaufrufs. Dieses Array wird verwendet, um alle Dateipfade zu speichern, die an die aktuelle Hierarchie gescannt wurden.
- Fehlerbehandlung : Überprüfungen zu IS_DIR und Opendir, um sicherzustellen, dass der Pfad effektiv und operativ ist, und die Robustheit verbessert.
- Directory_Separator : Verwenden Sie PHP-integrierte konstante Verzeichnis.
- Rekursive Anrufe und verschmelzen :
- Wenn ein Unterverzeichnis auftritt (IS_DIR ($ NewPath)), wird die Funktion von GetallFilePathsrecursive ($ Newpath) rekursiv aufgerufen.
- Der Sub-Call gibt ein Array aller von ihm gesammelten Dateipfade zurück.
- Array_Merge ($ allFilepaths, ...) fusioniert das vom Sub-Call zurückgegebene Array mit den $ allFilepathen des aktuellen Levels. Die Schlüsselrolle von Array_Merge besteht darin, dass es zwei oder mehr Zahlen zu einem Neuarray kombiniert, wodurch es abflacht und das Ergebnis einer verschachtelten Array -Struktur vermeidet.
- Dateiverarbeitung : Wenn eine Datei auftritt (sonst Block), fügen Sie den vollständigen Pfad der Datei $ Newpath direkt zu $ allFilepaths hinzu.
- Closedir ($ dirhandle) : Schließe das Verzeichnisgriff vor dem Ende der Funktion ist eine gute Programmiergewohnheit, um die Systemressourcen freizugeben.
- Return $ allFilepaths; : Dies ist der kritischste Schritt. Jeder GetAllFilepathsrecursive-Anruf muss das vollständige Array von Dateipfaden zurückgeben, das er in der aktuellen Hierarchie und allen Sub-hierarchien gesammelt hat. Auf diese Weise kann der übergeordnete Anruf diese Ergebnisse empfangen und zusammenfassen.
Notizen und Best Practices
- Speicherverwaltung : Für sehr große oder tiefe Dateisysteme können rekursive Anrufe einen Stapelüberlauf oder eine übermäßige Anzahl von Pfaden verursachen, die gesammelt werden, um Speicherüberlauf zu verursachen. In PHP wird es normalerweise durch Hinzufügen von memory_limit und xdebug.max_nesting_level (bei Verwendung von Xdebug) gemindert. Dies ist jedoch nicht die grundlegende Lösung. In extremen Fällen erwägen Sie iterative Methoden (z. B. SplfileObject, RecursiveInRectoryToryIterator) oder PHP 7 -Generator (Ausbeute), um die Speicherverwendung zu optimieren.
- Fehlerbehandlung : In Produktionsumgebungen sollten vollständigere Fehlerbehandlungsmechanismen hinzugefügt werden, z.
- Leistungsüberlegungen : Array_Merge erstellt jedes Mal ein Neuarray, wenn es wiederholt wird, was für massive Dateien bestimmte Leistungsaufwand für massive Dateien bringen kann. Wenn die Leistung ein äußerst kritischer Faktor ist, sollten Sie ein Array extern definieren und an eine rekursive Funktion (Funktion & Readdirs ($ Path & $ -Ergebnis)) über die Referenz übergeben. Dies erhöht jedoch die Komplexität des Codes und der potenziellen Nebenwirkungen, die normalerweise nicht als bevorzugte Wahl empfohlen werden.
- Verzeichnistrennzeichen : Verwenden Sie immer Directory_separator, um die Portabilität des Codes für verschiedene Betriebssysteme sicherzustellen.
- Filterbedingungen : Entsprechend den tatsächlichen Anforderungen können Sie der Datei- und Verzeichnisverarbeitungslogik flexibel mehr Filterbedingungen hinzufügen, z. B. Filterung basierend auf Dateierweiterung, Größe, Änderungszeit usw.
Zusammenfassen
Der Schlüssel zum korrekten Sammeln und Aggregieren führt zu rekursiven PHP -Funktionen besteht darin, den Werttransfermechanismus von Funktionsparametern zu verstehen und den Rückgabewert der Funktion geschickt zu verwenden. Wenn jeder rekursive Anruf die Ergebnisse zurückgibt, die es verarbeitet, und der übergeordnete Anruf für die Zusammenführung dieser Ergebnisse verantwortlich ist, können wir einen robusten und effizienten rekursiven Algorithmus erstellen. Die von diesem Tutorial bereitgestellten Beispiele des Dateisystems lösen nicht nur das Problem der rekursiven Ergebnissammlung, sondern zeigen auch, wie professioneller und wartbarer PHP -Code in praktischen Anwendungen geschrieben wird.
Das obige ist der detaillierte Inhalt vonErholungsergebnisse der Rekursivfunktion von PHP: Erstellen eines Dateisystemscanners. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Stock Market GPT
KI-gestützte Anlageforschung für intelligentere Entscheidungen

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

UseFilter_var () tovalateMailSyntaxandCheckdnsrr () tuverifyDomainMxRecords.Example: $ EMAMME = "User@example.com"; if (f ilter_var ($ mail, filter_validate_email) && checkDnsrr (explode ('@', $ mail) [1], 'mx') {echo "validandDeliverableMail & qu

UseUnSerialize (Serialize ($ OBJ)) FODEPCOPYPYWIEDALLDATAISSERIALIZIABLE; Andernfalls implementieren Sie __Clone () TomanuelleduplicatenestoBjectSandavoidSharedReferences.

Usearray_merge () tocombinearrays, überschreibende DuplicatestringKeysandReindexingnumericKeys;

In diesem Artikel wird eingehalten, wie man Fallanweisungen verwendet, um eine bedingte Aggregation in MySQL durchzuführen, um eine bedingte Summierung und Zählung bestimmter Felder zu erreichen. In einem praktischen Abonnement -System -Fall zeigt es, wie die Gesamtdauer und Anzahl der Ereignisse dynamisch auf der Grundlage des Datensatzstatus (z. B. "Ende" und "Abbrechen") berechnet werden kann, wodurch die Einschränkungen herkömmlicher Summenfunktionen überwunden werden, die den Anforderungen der komplexen bedingten Aggregation nicht erfüllen können. Das Tutorial analysiert die Anwendung von Fallanweisungen in Summenfunktionen im Detail und betont die Bedeutung von Koaleszen, wenn es sich um die möglichen Nullwerte des linken Join befasst.

NamespacesinphporganizeCodeAndPreventnamingConflictsByGroupingclasses, Schnittstellen, Funktionen und Constantsunderaspecificname.2.DefineAnaceStHenameSpaceKeyWorthetopoFafile, gefolgt von BythenameSpacename, solcheasapp \ controllers.3.

The__call () methodistiggeredWenaninAccessibleorundEfinedMethodiscalledonanObject, erlaubt CustomHandlingByaccepthodnameandargumente, ashownwhencallingundEfinedMethodselikesayhello (). 2.The__get () methodisinvokedInacescessininginingininginingininginingininginingininginingincessibleceschessibleChessibleChessibleornonon-EX

ToupDateadatabaserecordinphp, FirstConnectusepdoOrmysqli, ThenuSePreparedStatementStoExexexeSecuresQLUPDateQuery.example: $ pdo = newpdo ("MySQL: Host = LocalHost; dbname = your_database", $ username, $ username, $ username);

Usepathinfo ($ filename, pathinfo_extension) togetTheFilextesion; itrelablyHandlesMultiPleDOTSandgeCases, ReturningTheExtesion (z.
