Table des matières
Introduction: le défi de la collection de la récursivité et des résultats
Analyse des erreurs courantes: pourquoi est-il invalide de passer directement les tableaux?
Core de solution: Résultats agrégés à l'aide de valeurs de retour de fonction
Construisez un collecteur de chemins de fichiers efficace
Notes et meilleures pratiques
Résumer
Maison développement back-end tutoriel php PHP Recursive Fonction Results Collection: Construire un scanner de système de fichiers

PHP Recursive Fonction Results Collection: Construire un scanner de système de fichiers

Oct 06, 2025 am 10:09 AM

PHP Recursive Fonction Results Collection: Construire un scanner de système de fichiers

Ce didacticiel explore en profondeur la façon de collecter et d'agréger correctement les résultats dans les fonctions récursives PHP, en particulier pour les scénarios de numérisation du système de fichiers. En analysant les erreurs courantes, nous montrerons comment utiliser le mécanisme de valeur de retour de la fonction pour créer un collecteur de chemins de fichiers / répertoires récursif efficace et maintenable pour s'assurer que les données de toutes les sous-répertoires peuvent être correctement capturées et renvoyées.

Introduction: le défi de la collection de la récursivité et des résultats

La récursivité est une puissante technique de programmation qui permet aux fonctions de résoudre des problèmes en s'appelant, en particulier pour le traitement des données avec des structures auto-similaires, telles que les structures d'arbres ou les systèmes de fichiers. Cependant, la collecte et l'agrégation des résultats en appels récursifs rencontrent souvent des défis. Lorsque les données doivent être accumulées dans plusieurs niveaux récursifs, comment s'assurer que les résultats de tous les sous-appels peuvent être correctement transmis et fusionnés dans l'ensemble de résultats finaux est un problème clé pour les développeurs.

Analyse des erreurs courantes: pourquoi est-il invalide de passer directement les tableaux?

De nombreux débutants rencontrent un problème commun lorsque vous essayez de collecter des données à partir de fonctions récursives: passer un tableau comme argument à la fonction récursive et s'attendre à les modifier à l'intérieur de la fonction pour accumuler des données à tous les niveaux récursifs.

Considérez l'extrait de code suivant (basé sur la question d'origine):

 Fonction ReadDirs ($ path, $ result = []) // $ Le résultat est passé par valeur par défaut {
    $ dirhandle = opendir ($ path);
    tandis que ($ item = readdir ($ dirhandle)) 
    {
       $ newpath = $ path. "/". $ item;
       if (is_dir ($ newpath) && $ item! = '.' && $ item! = '..') 
       { 
         ReadDirs ($ newpath, $ Result); // Appel récursivement, passant une copie de $ result}
       elseif (! is_dir ($ newpath) && $ item! = '.ds_store' && $ item! = '.' && $ item! = '..')
       { 
          // écho "$ path <br>"; // Imprime le répertoire actuel Path $ Result [] = $ path; // Modifiez la copie de résultat $ de la fonction actuelle Retour $ Résultat; // Renvoie prématurément interrompre le scan du répertoire actuel et interrompt l'attente du parent du résultat}
    }
    // s'il n'y a pas de fichier ou si le fichier est traité dans le répertoire actuel, il renverra implicitement Null ou Vide $ Résultat
}

Analyse des problèmes:

  1. Passer par valeur : en php, les paramètres de fonction sont passés par valeur par défaut. Cela signifie que lorsque ReadDirs ($ newPath, $ result) est appelé, une copie du tableau de résultat $ est transmise à la sous-fonction. Toute modification de la copie de résultat $ par la fonction enfant n'affectera pas le tableau de résultat $ d'origine dans la fonction parent. Par conséquent, le résultat ne peut pas être accumulé entre les appels récursifs.
  2. Retour prématuré : le résultat de retour $; L'instruction dans le bloc ELLEIF fera quitter la fonction immédiatement la sortie après avoir trouvé le premier fichier et ajouté le chemin du répertoire vers $ le résultat. Cela empêche non seulement la numérisation d'autres fichiers et sous-répertoires dans le répertoire actuel, mais il est également impossible pour l'appel parent de continuer à collecter des données.

Core de solution: Résultats agrégés à l'aide de valeurs de retour de fonction

La clé pour résoudre le problème ci-dessus est de modifier la manière de penser: la fonction récursive ne doit pas s'appuyer sur la modification des paramètres du tableau passé pour accumuler les résultats, mais doit renvoyer les résultats qu'il a collectés au niveau actuel. L'appelant parent est responsable de la réception des résultats renvoyés par l'enfant et de la fusion dans son propre ensemble de résultats.

Cette approche garantit que chaque appel de fonction a des responsabilités claires: le traitement des données au niveau actuel et le renvoi d'un ensemble de données complet contenant les résultats du niveau actuel et de tous les agrégats de sous-niveau.

Construisez un collecteur de chemins de fichiers efficace

Voici un exemple de fonction récursif PHP optimisé conçu pour scanner un répertoire spécifié et tous ses sous-répertoires et renvoyer un tableau aplati contenant les chemins complets de tous les fichiers (non-répertoires).

  Php

/ **
 * Analyser récursivement le répertoire spécifié et ses sous-répertoires pour collecter le chemin complet vers tous les fichiers.
 *
 * @param String $ chemin le chemin du chemin pour scanner le répertoire de démarrage.
 * @return Array contenant les chemins complets de tous les fichiers.
 * /
fonction getallFilepathSRecursive (String $ path): Array
{
    $ allFilePaths = []; // Initialisez le tableau de résultat du niveau actuel // Vérifiez si le chemin est valide et est un répertoire ouvert if (! Is_dir ($ path) ||! ($ Dirhandle = opendir ($ path))) {
        // Le chemin est invalide ou le répertoire ne peut pas être ouvert, renvoyant le tableau vide error_log ("Impossible d'ouvrir le répertoire:". $ Path);
        retour $ AllFilepaths;
    }

    while (false! == ($ item = readdir ($ dirhandle))) {
        // ignore le répertoire actuel '.' et le répertoire précédent '..'
        if ($ item === '.' || $ item === '..') {
            continuer;
        }

        // Créez un nouveau chemin complet, en utilisant le séparateur de répertoire multiplateforme $ newpath = $ path. Directory_separator. $ article;

        if (is_dir ($ newpath)) {
            // S'il s'agit d'un répertoire, appelez lui-même de manière récursive et combinez le résultat renvoyé avec le numéro de résultat actuel et // array_merge est utilisé pour aplatir le tableau pour éviter de nicher $ allFilepaths = array_merge ($ allFilepathes, getAllFilePathSrecursive ($ newPathe));
        } autre {
            // S'il s'agit d'un fichier, ajoutez son chemin complet au tableau de résultat // D'autres conditions de filtrage de fichiers peuvent être ajoutées au besoin, comme l'exclusion .ds_store
            if ($ item! == '.ds_store') {// exclure les fichiers cachés de macOS $ allFilePaths [] = $ newPath;
            }
        }
    }
    CLOLIRIR ($ dirhandle); // Fermez la poignée du répertoire et libérez le retour de ressources $ AllFilePaths; // renvoie tous les chemins de fichier collectés au niveau actuel}

// Exemple d'utilisation:
$ basepath = "/ utilisateurs / myComputer / Documents / www / Photos_projet"; // Veuillez le remplacer par votre chemin réel // Vérifiez si le chemin de départ existe et est un répertoire if (! Is_dir ($ basepath)) {
    Echo "Erreur: le chemin de départ n'existe pas ou n'est pas un répertoire. \ n";
} autre {
    $ CollectedFilePaths = GetAllFilePathSrecursive ($ basepath);

    echo "--- le chemin du fichier collecté --- \ n";
    if (vide ($ collectéfilepaths)) {
        echo "aucun fichier trouvé. \ n";
    } autre {
        foreach ($ collectéfilepaths comme $ filepath) {
            Echo $ filepath. "\ n";
        }
        Echo "collecté au total". Count ($ collectéfilepaths). "fichiers. \ n";
    }
    // Vous pouvez également utiliser var_dump ($ collectéFilePaths); Pour afficher la structure du tableau}

?>

Analyse de code:

  1. $ allFilePaths = []; : Initialisez un tableau vide local au début de chaque appel de fonction. Ce tableau sera utilisé pour stocker tous les chemins de fichier analysés vers la hiérarchie actuelle.
  2. Gestion des erreurs : Ajout de vérifications sur IS_DIR et OpenDir pour s'assurer que le chemin est efficace et opérationnel, et améliore la robustesse.
  3. Directory_Separator : Utilisez PHP constant intégré Directory_Separator pour créer le chemin d'accès, ce qui garantit la compatibilité du code sur différents systèmes d'exploitation tels que Windows et Unix-Like Systems.
  4. Appels récursifs et fusion :
    • Lorsqu'un sous-répertoire est rencontré (IS_DIR ($ newpath)), la fonction appellera récursivement getAllFilePathSrecursive ($ newpath).
    • Le sous-appel renvoie un tableau de tous les chemins de fichier qu'il collectionne.
    • Array_merge ($ AllFilePaths, ...) Fumente le tableau renvoyé par le sous-appel avec les $ AllFilePaths du niveau actuel. Le rôle clé de Array_merge est qu'il combine deux nombres ou plus dans un nouveau tableau, l'aplatirant ainsi et évitant le résultat d'une structure de réseau imbriquée.
  5. Traitement de fichiers : lorsqu'un fichier est rencontré (Else Block), ajoutez le chemin complet du fichier $ newpath directement à $ AllFilePaths.
  6. CLOLIRIR ($ dirhandle) : fermé la poignée du répertoire avant la fin de la fonction est une bonne habitude de programmation pour libérer les ressources système.
  7. retour $ AllFilepaths; : C'est l'étape la plus critique. Chaque appel GetAllFilePathSrecursive doit renvoyer le tableau complet des chemins de fichier qu'il a collectés dans la hiérarchie actuelle et toutes ses sous-hiérarchies. De cette façon, l'appel parent peut recevoir et agréger ces résultats.

Notes et meilleures pratiques

  • Gestion de la mémoire : pour les systèmes de fichiers très grands ou profonds, les appels récursifs peuvent provoquer un débordement de pile ou un nombre excessif de chemins collectés pour provoquer un débordement de mémoire. En PHP, il est généralement atténué en ajoutant Memory_limit et xdebug.max_nesting_level (si vous utilisez xdebug), mais ce n'est pas la solution fondamentale. Pour les cas extrêmes, envisagez d'utiliser des méthodes itératives (telles que SPLFileObject, RecursiveDirectoryiterator) ou le générateur PHP 7 (rendement) pour optimiser l'utilisation de la mémoire.
  • Gestion des erreurs : Dans les environnements de production, des mécanismes de gestion des erreurs plus complets doivent être ajoutés, tels que la capture et la journalisation de l'échec possible des fonctions telles que OpenDir et Readdir.
  • Considérations de performances : Array_merge crée un nouveau tableau à chaque fois qu'il se reproduit, ce qui peut apporter certaines frais généraux de performances pour les fichiers massifs. Si les performances sont un facteur extrêmement critique, envisagez de définir un tableau à l'extérieur et de le passer à une fonction récursive (fonction et readdirs ($ path, & $ result)) par référence, mais cela augmente la complexité du code et des effets secondaires potentiels, qui n'est généralement pas recommandé comme choix préféré.
  • Séparateur de répertoire : utilisez toujours Directory_Separator pour assurer la portabilité du code sur différents systèmes d'exploitation.
  • Conditions de filtrage : Selon les besoins réels, vous pouvez ajouter de manière flexible les conditions de filtrage à la logique de traitement du fichier et du répertoire, telles que le filtrage en fonction de l'extension du fichier, de la taille, du temps de modification, etc.

Résumer

La clé de la collecte et de l'agrégation correctes dans les fonctions récursives PHP est de comprendre le mécanisme de transfert de valeur des paramètres de fonction et d'utiliser habilement la valeur de retour de la fonction. En ayant chaque appel récursif renvoie les résultats qu'il traite et l'appel parent est responsable de la fusion de ces résultats, nous pouvons créer un algorithme récursif robuste et efficace. Les exemples de numérisation du système de fichiers fournis par ce didacticiel résolvent non seulement le problème de la collection de résultats récursifs, mais montrent également comment rédiger un code PHP professionnel et maintenable dans des applications pratiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Stock Market GPT

Stock Market GPT

Recherche d'investissement basée sur l'IA pour des décisions plus intelligentes

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Comment vérifier si une adresse e-mail est valide en PHP? Comment vérifier si une adresse e-mail est valide en PHP? Sep 21, 2025 am 04:07 AM

Usefilter_var () tovalidateemailsyntaxandcheckdnsrr () toverifydomainmxrecords.example: $ email = "user@example.com"; if (f ilter_var ($ e-mail, filter_validate_email) && checkdnsrr (explosage ('@', $ e-mail) [1], 'mx')) {echo "ValidAndDeliverableMail & Qu

Comment faire une copie profonde ou un clone d'un objet en PHP? Comment faire une copie profonde ou un clone d'un objet en PHP? Sep 21, 2025 am 12:30 AM

UseUnserialize (serialize ($ obj)) FordopcopyingwhenallDataisSerializable; Sinon, implémentez__Clone () TomanuallyDuplicatesedObjectsAndavoidSharedReferences.

Comment fusionner deux tableaux en php? Comment fusionner deux tableaux en php? Sep 21, 2025 am 12:26 AM

UseArray_merge () toCombineArrays, écrasant leduplicatestringKeysAndreIndexingNumericKeys; ForsimplecCaTencatenation, en particulierInphp5.6, usethesplatoperator [... $ array1, ... $ array2].

MySQL Aggrégation conditionnelle: Instruction de cas d'utilisation pour mettre en œuvre le résumé de la condition et le comptage des champs MySQL Aggrégation conditionnelle: Instruction de cas d'utilisation pour mettre en œuvre le résumé de la condition et le comptage des champs Sep 16, 2025 pm 02:39 PM

Cet article explique en profondeur comment utiliser les instructions de cas pour effectuer une agrégation conditionnelle dans MySQL pour atteindre la sommation conditionnelle et le comptage de champs spécifiques. Grâce à un cas de système d'abonnement pratique, il montre comment calculer dynamiquement la durée totale et le nombre d'événements en fonction de l'état des enregistrements (tels que "end" et "annuler"), surmontant ainsi les limites des fonctions de somme traditionnelles qui ne peuvent pas répondre aux besoins d'une agrégation conditionnelle complexe. Le tutoriel analyse en détail l'application des instructions de cas en détail et souligne l'importance de la fusion lorsqu'il s'agit des valeurs nulles possibles de la jointure gauche.

Comment utiliser des espaces de noms dans un projet PHP? Comment utiliser des espaces de noms dans un projet PHP? Sep 21, 2025 am 01:28 AM

NamespacesInphporganizEcodeAndPreventnamingConflictsBygroupingClasses, Interfaces, Functions et ConstantsunSunSaspecificName.2.DefineanamespaceusingTheNamesPaceSpaceKeyWordAtTopofaFile, suiviByTheNamesPacename, Suchasapp \ Controlers...USUSEUSEKEYWORDTOI

Quelles sont les méthodes magiques en PHP et fournissent un exemple de `__Call () 'et` __get ()'. Quelles sont les méthodes magiques en PHP et fournissent un exemple de `__Call () 'et` __get ()'. Sep 20, 2025 am 12:50 AM

La méthodiette () méthodiste axée sur le point de réviser la mise en œuvre de l'inscription, ce qui permet de faire de la maintenance à la qualité de qualité et

Comment mettre à jour un enregistrement dans une base de données avec PHP? Comment mettre à jour un enregistrement dans une base de données avec PHP? Sep 21, 2025 am 04:47 AM

ToupDateAdatabasereCorDinPhp, FirstConnectUsingPDoOrmysQLi, theNusepreparedStationStoExECUSEASECURSQLUPDATEQUERY.example: $ pdo = newPDO ("MySql: host = localhost; dbname = votre_database", $ username, $ mot de passe); $ sql = "dameussem =.

Comment obtenir l'extension de fichier en php? Comment obtenir l'extension de fichier en php? Sep 20, 2025 am 05:11 AM

UsePathinfo ($ nom de fichier, pathinfo_extension) togetThefileExtension; itreliabblyHandlesMultipledototsEdGasases, renvoyantTheExtension (par exemple, "pdf") oranemptystringefNoneExists.

See all articles