<?php
/**
* Recursively find a file by its name in a directory.
*
* Found files are cached onto the current session for
* quicker access next time.
*
* Requires PHP 5
*
* by theredhead
*/
class KFileFinder
{
public $dir = null;
public $file = null;
public function __construct( $file = null, $dir = null )
{
// did we give a directory?
if ( $dir == null )
{
// no, start searching under the servers public root
$this->dir = realpath( $_SERVER[ 'DOCUMENT_ROOT' ].'/../' );
} else {
$this->dir = $dir;
}
// let the instance know what file to look for
if ( $file !== null )
{
$this->file = $file;
}
return $this;
}
// static method: $result = KFileFinder::findFile( 'guestbook.xml' );
public static function findFile( $file, $dir = null )
{
$finder = new KFileFinder( $file, $dir );
$result = $finder->find();
unset($finder);
return $result;
}
// instance method: $result = $myFinder->find( 'guestbook.xml' );
public function find( $dir = null )
{
// cache found file into the session so we only have to search
// for it the first time and when it moved
if (isset($_SESSION[ 'KFileFinder' ][ $this->file ]) &&
file_exists($_SESSION[ 'KFileFinder' ][ $this->file ]))
{
return $_SESSION[ 'KFileFinder' ][ $this->file ];
}
$found = false;
if ( $dir == null )
{
$d = $this->dir;
} else {
$d = $dir;
}
$iterator = new DirectoryIterator( $d );
// the loop
while( $iterator->valid() && $found == false )
{
if ( !$iterator->isDot() && $iterator->isDir() )
{
$pathToCheck = $iterator->getPathname().'/'.$this->file;
// test if the file existts and if we can read it
if ( file_exists( $pathToCheck ) && is_readable( $pathToCheck ))
{
$found = $pathToCheck;
} else {
$found = $this->find( $iterator->getPathname() );
}
}
$iterator->next();
}
// cache the result
$_SESSION[ 'KFileFinder' ][ $this->file ] = $found;
return $found;
}
}
?>