php搜索从结尾开始的目录

时间:2015-04-13 19:14:24

标签: php recursion

我有这个PHP代码,但之前只编写过一个递归函数。我想从一个特定的子目录开始,检查是否存在文件。如果它不存在于目录中,我想检查该文件的父文件夹,然后递归继续,直到我要么找不到该文件并返回""或找到文件并返回其内容。这是我的功能:

/**
*   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 "";
            }
        }
    }
}

所以,当我打电话给它时,我这样做:

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

让我们说我想找的文件位于名为" segment2"的目录中。该功能永远找不到它。 array_pop函数不会弹出数组末尾的元素,然后调用findSidebarFromPath函数。

1 个答案:

答案 0 :(得分:2)

如果你把它写成一个独立的功能,它可能对你在其他领域更有用。在我们了解它的工作原理后,我们将向您展示如何向您的班级添加可以使用它的公共功能。

/**
 * @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);
}

检查ideone上的示例输出。


所以这里有如何使用它

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

以下是如何将它与您的课程整合的方法。请注意,此公共函数具有与原始代码中相同的API

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";
  }
}

补充说明

如果$_SERVER["DOCUMENT_ROOT"]/var/www ...

  1. 检查/var/www/foo/bar/qux/sidebar.html,如果存在则返回
  2. 检查/var/www/foo/bar/sidebar.html,如果存在则返回
  3. 检查/var/www/foo/sidebar.html,如果存在则返回
  4. 检查/var/www/sidebar.html,如果存在则返回
  5. 因为我们到了根(/var/www),所以不会再进行搜索
  6. 如果上述任何一个
  7. 中没有sidebar.html,则返回false

    这里的功能相同,删除了解释性注释

    /**
     * @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);
    }
    

    您可能还需要考虑使用DIRECTORY_SEPARATOR而不是硬编码"/",以便可以在各种平台上可靠地使用此代码。