J'ai un serveur avec beaucoup de fichiers dans divers dossiers, sous-dossiers et sous-sous-dossiers.
J'essaie de créer une page search.php qui serait utilisée pour rechercher un fichier spécifique sur l'ensemble du serveur. Si le fichier est trouvé, renvoyez le chemin de l'emplacement pour afficher un lien de téléchargement.
Voici ce que j'ai jusqu'à présent:
$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>";
}
Le script fonctionne parfaitement si le fichier se trouve à la racine de mon nom de domaine ... Maintenant, j'essaie de trouver un moyen de le faire aussi pour analyser les sous-dossiers et les sous-sous-dossiers, mais je suis coincé ici.
Il y a 2 façons.
Utilisez glob
pour effectuer une recherche récursive:
<?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;
}
?>
Utilisez 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
est fourni avec PHP5 tandis que glob
provient de PHP4. Les deux peuvent faire le travail, c'est à vous de décider.
Ceci retourne le chemin complet du fichier
function rsearch($folder, $pattern) {
$iti = new RecursiveDirectoryIterator($folder);
foreach(new RecursiveIteratorIterator($iti) as $file){
if(strpos($file , $pattern) !== false){
return $file;
}
}
return false;
}
appeler la fonction:
$filepath = rsearch('/home/directory/thisdir/', "/findthisfile.jpg");
Et cela revient comme:
/home/directory/thisdir/subdir/findthisfile.jpg
Vous pouvez améliorer cette fonction pour trouver plusieurs fichiers comme tous les fichiers jpeg:
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;
}
Cela peut appeler comme:
$filepaths = rsearch('/home/directory/thisdir/', array('jpeg', 'jpg') );
Je souhaite proposer une autre solution simple pour les cas où vous pouvez prévoir une profondeur maximale. Vous pouvez utiliser un modèle avec des accolades répertoriant toutes les profondeurs possibles de sous-dossiers.
Cet exemple autorise 0-3 sous-dossiers arbitraires:
glob("$root/{,*/,*/*/,*/*/*/}test_*.Zip", GLOB_BRACE);
Bien entendu, le motif en forme de contreventement pourrait être généré de manière procédurale.
En tant que solution complète à votre problème (c'était aussi mon problème):
<?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;
}
?>
Vous obtiendrez le chemin complet des articles que vous souhaitez trouver.