This is just a few functions I wipped up for the autoload function in PHP5. It will scan and record the available classes in a dir.
It first creates a list (if one isn't created) of the classes in the class directory and records it to a file. Then it checks the list to see if the class is listed and loads it if found. Next it will scan the class directory for the class and loads it if found. Else it throws an error. Also, if the class was found while scanning the dir, the class list is recreated. The other functions are used for autoload.
Let me know if you see any errors, corrections, whatnot. I havn't had time to test this as I'm JUST starting my class repository. Thanks
<?php
define('CLASS_DIR', './classes'); // Directory containing all of your classs (supports sub dirs)
define('DIR_SEP', '/'); // Directory seperator for those who use it..
define('PHP_EXT', 'php'); // PHP extension ex: php or php5 (in case you've changed it)
// This is called for an undeclared class.
function __autoload(string $class)
{
// You can comment this out if you would like, just a notice.
trigger_error("The class [$class] is undeclared, attempting to find the class file.", E_USER_NOTICE);
// If the class list file doesn't exist create it.
if (!file_exists(CLASS_DIR.DIR_SEP.'list.txt')) {
if (($list = createClassList()) !== false)
writeClassList($list);
}
// First try to find the class in the list.
if (!findClass($class)) {
// Next try scanning the class dir.
if (!scanClass($class)) {
trigger_error("Could not find, include, and declare the class [$class].", E_USER_WARNING);
return(false);
} else {
// If the class was found above, recreate the list.
if (($list = createClassList()) !== false)
writeClassList($list);
}
}
}
// Finds a class in the recorded list and includes it.
function findClass(string $class)
{
$rtn = false;
$file = CLASS_DIR.DIR_SEP.'list.txt';
// Try to get the class list file.
if (($list = file_get_contents($file)) !== false) {
if (($list = unserialize($list)) !== false) {
// See if the class is in the list.
if (array_key_exists($class, $list)) {
include_once($list[$class]);
$rtn = true;
}
} else {
trigger_error("Could not unserialize the class list from the file [$file].", E_USER_WARNING);
}
} else {
trigger_error("Could not get the class list from the file [$file].", E_USER_WARNING);
}
return($rtn);
}
// Scans the class dir for a class, (supports sub dirs).
function scanClass(string $class, string $dir=CLASS_DIR)
{
// Get a list of the dir.
if (($files = scandir($dir)) !== false) {
$dirs1 = array(); // Dirs with class name within the dir name.
$dirs2 = array(); // The other dirs (other than above).
// Check each item to see if it's a file or dir.
foreach ($files as $file) {
// If it's a dir add it to the list to check.
if (is_dir($dir.DIR_SEP.$file) && !in_array($file, array('.','..'))) {
// If the class name is in the dir name check it first.
if (stristr($file, $class) !== false)
$dirs1[] = $file;
else
$dirs2[] = $file;
// If it's a file and is the correct class include the file.
} elseif (is_file($dir.DIR_SEP.$file) && strcasecmp($file, $class.'.class.'.PHP_EXT) == 0) {
include_once($dir.DIR_SEP.$file);
return(true);
}
}
// Check the more likely dirs first and the rest second.
foreach ($dir1 as $dir_name) {
if (scanClass($class, $dir.DIR_SEP.$dir_name))
return(true);
}
foreach ($dir2 as $dir_name) {
if (scanClass($class, $dir.DIR_SEP.$dir_name))
return(true);
}
}
return(false);
}
// Scans the class dirs and returns an array with Array[ClassName] = FileLocation
function createClassList($list=array(), string $dir=CLASS_DIR)
{
// Get a list of the dir.
if (($items = scandir($dir)) !== false) {
foreach ($items as $item) {
// If it's a sub dir scan it.
if (is_dir($dir.DIR_SEP.$item) && !in_array($item, array('.','..'))) {
// If something went wrong while scanning the sub dir, return false.
if (($list = createClassList($list, $dir.DIR_SEP.$item)) === false)
return(false);
// If it's a class file add it to the list.
} elseif (is_file($dir.DIR_SEP.$item) && preg_match("/\.class\.".PHP_EXT."$/i", $item)) {
$class = str_ireplace('.class.'.PHP_EXT, '', $item);
// Detect if there is a duplicate class.
if (array_key_exists($class, $list)) {
trigger_error("There are two class files with the same name [$class]. Each class must have a unique name.", E_USER_NOTICE);
return(false);
} else {
$list[$class] = $dir.DIR_SEP.$item;
}
}
}
} else {
return(false);
}
return($list);
}
// Just writes the class list to the file.
function writeClassList($list)
{
$file = CLASS_DIR.DIR_SEP.'list.txt';
$list = serialize($list);
if (file_put_contents($file, $list) === false) {
trigger_error("Could not write the class list to the file [$file].", E_USER_WARNING);
}
}
?>