web-dev-qa-db-de.com

php glob - Unterordner nach einer Datei durchsuchen

Ich habe einen Server mit vielen Dateien in verschiedenen Ordnern, Unterordnern und Unterunterordnern. 

Ich versuche, eine search.php-Seite zu erstellen, mit der der gesamte Server nach einer bestimmten Datei durchsucht werden kann. Wenn die Datei gefunden wurde, geben Sie den Pfad zum Pfad ein, um einen Download-Link anzuzeigen.

Folgendes habe ich bisher:

$root = $_SERVER['DOCUMENT_ROOT'];
$search = "test.Zip";
$found_files = glob("$root/*/test.Zip");
$downloadlink = str_replace("$root/", "", $found_files[0]);
if (!empty($downloadlink)) {
    echo "<a href=\"http://www.example.com/$downloadlink\">$search</a>";
} 

Das Skript funktioniert einwandfrei, wenn sich die Datei in der Wurzel meines Domainnamens befindet. Nun versuche ich, einen Weg zu finden, in dem es auch Unterordner und Unterordner durchsucht.

26
Winston Smith

Es gibt zwei Möglichkeiten.

Verwenden Sie glob, um eine rekursive Suche durchzuführen:

<?php

// Does not support flag GLOB_BRACE
function rglob($pattern, $flags = 0) {
    $files = glob($pattern, $flags); 
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $files = array_merge($files, rglob($dir.'/'.basename($pattern), $flags));
    }
    return $files;
}

?>

Verwenden Sie RecursiveDirectoryIterator

<?php
function rsearch($folder, $pattern) {
    $dir = new RecursiveDirectoryIterator($folder);
    $ite = new RecursiveIteratorIterator($dir);
    $files = new RegexIterator($ite, $pattern, RegexIterator::GET_MATCH);
    $fileList = array();
    foreach($files as $file) {
        $fileList = array_merge($fileList, $file);
    }
    return $fileList;
}
?>

RecursiveDirectoryIterator wird mit PHP5 geliefert, während glob aus PHP4 stammt. Beide können die Arbeit erledigen, es liegt an Ihnen.

51
Tony Chen

Dies gibt den vollständigen Pfad zur Datei zurück

function rsearch($folder, $pattern) {
    $iti = new RecursiveDirectoryIterator($folder);
    foreach(new RecursiveIteratorIterator($iti) as $file){
         if(strpos($file , $pattern) !== false){
            return $file;
         }
    }
    return false;
}

rufen Sie die Funktion auf:

$filepath = rsearch('/home/directory/thisdir/', "/findthisfile.jpg");

Und das ist Renditen wie:

/home/directory/thisdir/subdir/findthisfile.jpg

Sie können diese Funktion verbessern, um mehrere Dateien wie alle JPEG-Dateien zu finden:

function rsearch($folder, $pattern_array) {
    $return = array();
    $iti = new RecursiveDirectoryIterator($folder);
    foreach(new RecursiveIteratorIterator($iti) as $file){
        if (in_array(strtolower(array_pop(explode('.', $file))), $pattern_array)){
            $return[] = $file;
        }
    }
    return $return;
}

Dies kann aufgerufen werden als: 

$filepaths = rsearch('/home/directory/thisdir/', array('jpeg', 'jpg') );

Ref: https://stackoverflow.com/a/1860417/219112

4
Sadee

Ich möchte eine weitere einfache Alternative für Fälle bereitstellen, in denen Sie eine maximale Tiefe vorhersagen können. Sie können ein Muster mit Klammern verwenden, das alle möglichen Unterordner-Tiefen auflistet.

Dieses Beispiel erlaubt 0-3 beliebige Unterordner:

glob("$root/{,*/,*/*/,*/*/*/}test_*.Zip", GLOB_BRACE);

Natürlich könnte das versteifte Muster prozedural erzeugt werden.

1

Als vollständige Lösung für Ihr Problem (das war auch mein Problem):

<?php
function rsearch($folder, $pattern) {
    $dir = new RecursiveDirectoryIterator($folder);
    $ite = new RecursiveIteratorIterator($dir);
    $files = new RegexIterator($ite, $pattern, RegexIterator::MATCH);
    $fileList = array();
    foreach($files as $file) {
         $fileList[] = $file->getPathName();
    }
    return $fileList;
}
?>

Sie erhalten den vollständigen Pfad der Elemente, die Sie finden möchten.

0
metzelder