/ / php Durchsucht ein Verzeichnis, das am Ende beginnt - php, Rekursion

php Durchsuchen eines Verzeichnisses beginnend am Ende - php, Rekursion

Ich habe diesen PHP-Code aber nur einen geschriebenrekursive Funktion vor. Ich möchte in einem bestimmten Unterverzeichnis beginnen und prüfen, ob eine Datei vorhanden ist. Wenn es nicht im Verzeichnis vorhanden ist, möchte ich den übergeordneten Ordner auf die Datei überprüfen und dann rekursiv fortfahren, bis ich entweder die Datei nicht finde und zurückgebe oder die Datei finde und ihren Inhalt zurückgebe. Hier ist meine Funktion:

/**
*   Recursive function to get sidebar from path and look up tree until we either
*   find it or return blank.
*/
class MyClass{
public function findSidebarFromPath($path){
if(file_exists($_SERVER["DOCUMENT_ROOT"].implode("/", $path)."/sidebar.html")){
return file_get_contents($_SERVER["DOCUMENT_ROOT"].implode("/", $path)."/sidebar.html");
} else {
if(count($path) > 0){
# pop element off end of array.
$discard = array_pop($path);
$this->findSidebarFromPath($path);
} else {
return "";
}
}
}
}

Wenn ich es also nenne, mache ich Folgendes:

$myclass = new MyClass();
$myclass->findSidebarFromPath(array("segment1", "segment2", "segment3"));

Angenommen, die Datei, die ich zu finden versuche, befindet sich in einemVerzeichnis mit dem Namen "segment2". Die Funktion findet es nie. Die Funktion array_pop entfernt das Element nicht vom Ende des Arrays und ruft dann die Funktion findSidebarFromPath auf.

Antworten:

2 für die Antwort № 1

Wenn Sie dies als eigenständige Funktion schreiben, wird eswird Ihnen wahrscheinlich in anderen Bereichen nützlicher sein. Nachdem wir verstanden haben, wie es funktioniert, zeigen wir Ihnen, wie Sie Ihrer Klasse eine öffentliche Funktion hinzufügen können, die sie nutzen kann.

/**
* @param $root string - the shallowest path to search in
* @param $path string - the deepest path to search; this gets appended to $root
* @param $filename string - the file to search for
* @return mixed - string file contents or false if no file is found
*/
function findFile($root, $path, $filename) {
// create auxiliary function that takes args in format we want
$findFileAux = function($cwd, $filename) use (&$findFileAux, $root) {
// resolve the complete filename
$file = "{$cwd}/{$filename}";
// if the file exists, return the contents
if (file_exists($file)) return file_get_contents($file);
// if the cwd has already reached the root, do not go up a directory; return false instead
if ($cwd === $root) return false;
// otherwise check the above directory
return $findFileAux(dirname($cwd), $filename);
};
// starting checking for the file at the deepest segment
return $findFileAux("{$root}/{$path}", $filename);
}

Überprüfen Sie die Beispielausgabe auf Ideone.


Also hier ist, wie man es benutzt

findFile($_SERVER["DOCUMENT_ROOT"], "foo/bar/qux", "sidebar.html");

So würden Sie es in Ihre Klasse integrieren. Beachten Sie, dass diese öffentliche Funktion die gleiche API wie in Ihrem ursprünglichen Code hat

class MyClass {
/**
* @param $path array - path segments to search in
* @return mixed - string file contents or false if sidebar is not found
*/
public function findSidebarFromPath($path) {
// Here we call upon the function we wrote above
// making sure to `join` the path segments into a string
return findFile($_SERVER["DOCUMENT_ROOT"], join("/", $path), "sidebar.html";
}
}

Zusätzliche Erklärung

Ob $_SERVER["DOCUMENT_ROOT"] ist /var/www...

  1. Prüfen /var/www/foo/bar/qux/sidebar.htmlRückgabe, falls vorhanden
  2. Prüfen /var/www/foo/bar/sidebar.htmlRückgabe, falls vorhanden
  3. Prüfen /var/www/foo/sidebar.htmlRückgabe, falls vorhanden
  4. Prüfen /var/www/sidebar.htmlRückgabe, falls vorhanden
  5. Weil wir zur Wurzel kamen (/var/www) Es werden keine weiteren Suchen durchgeführt
  6. Rückkehr false Wenn sidebar.html in keinem der oben genannten Bereiche vorhanden war

Hier ist die gleiche Funktion mit den erläuternden Kommentaren entfernt

/**
* @param $root string - the shallowest path to search in
* @param $path string - the deepest path to search; this gets appended to $root
* @param $filename string - the file to search for
* @return mixed - string file contents or false if no file is found
*/
function findFile($root, $path, $filename) {
$findFileAux = function($cwd, $filename) use (&$findFileAux, $root) {
$file = "{$cwd}/{$filename}";
if (file_exists($file)) return file_get_contents($file);
if ($cwd === $root) return false;
return $findFileAux(dirname($cwd), $filename);
};
return $findFileAux("{$root}/{$path}", $filename);
}

Vielleicht möchten Sie auch die Verwendung in Betracht ziehen DIRECTORY_SEPARATOR statt der fest codierten "/" Damit kann dieser Code zuverlässig auf einer Vielzahl von Plattformen verwendet werden.