Today I had an idea that seemed neat: a self-learning __autoload() function. The idea was that since PHP doesn't enforce the one class per file rule, or even have namespaces for hierarchical directory naming, it is fairly common to find several classes in a single file. This can get to be confusing if one tries to be conservative with the number of files they include.
To solve this problem, I wrote a small function that will traverse a directory tree and return a hash table of className => path.
$classes = array();
getClasses( ".", $classes );
// this is an ultra-simplistic implementation. it
// uses a global just so it doesn't have to reload
// with every iteration. a better implementation
// may be to wrap this all into a singleton class.
function __autoload( $className ) {
global $classes;
if( isset( $classes[$className] ) && file_exists( $classes[$className] ) ) {
require_once( $classes[$className] );
return true;
}
}
function getClasses( $path, &$classes, $fileNamePattern = null ) {
if( is_dir( $path ) ) {
$d = opendir( $path );
while( $fileName = readdir( $d ) ) {
if( preg_match( '/^\.\.?$/', $fileName ) ) { continue; }
// check to see that the filename matches the user's pattern
if( $fileNamePattern && !preg_match( $fileNamePattern, $fileName ) ) { continue; }
getClasses( "$path/$fileName", $classes );
}
closedir( $d );
} elseif( file_exists( $path ) ) {
// one could do this line by line if memory is an issue
$data = file_get_contents( $path );
preg_match_all( "/(class|interface)[\n\r\s]+(\w+)/", $data, $m );
foreach( $m[2] as $className ) {
$classes[$className] = $path;
}
}
}
While this could be made much more versatile with file modification times used
for rescanning files, caching between requests and the like, I have
just kept it simple to illustrate the main idea and let you improve
upon it as you so desire.