If you write this as a standalone function, it will probably be more useful to you in other areas. After we understand how it works, we'll show you how you can add a public function to your class that can utilize it.
/**
* @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);
}
Check the example output on ideone.
So here's how to use it
findFile($_SERVER["DOCUMENT_ROOT"], "foo/bar/qux", "sidebar.html");
Here's how you would integrate it with your class. Notice that this public function has the same API as in your original code
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";
}
}
Additional explanation
If $_SERVER["DOCUMENT_ROOT"]
is /var/www
...
- Check
/var/www/foo/bar/qux/sidebar.html
, return if exists
- Check
/var/www/foo/bar/sidebar.html
, return if exists
- Check
/var/www/foo/sidebar.html
, return if exists
- Check
/var/www/sidebar.html
, return if exists
- Because we got to the root (
/var/www
) no further searches will happen
- return
false
if sidebar.html did not exist in any of the above
Here's the same function with the explanatory comments removed
/**
* @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);
}
You might also want to consider using DIRECTORY_SEPARATOR
instead of the hard-coded "/"
so that this code could be used reliably on a variety of platforms.