dimgel
Новичок
раздаю src: __autoload(), рекурсиво сканирующая каталог classes...
Всем привет!
Вот, решил поделиться.
В условия резкой нехватки namespaces, я хотя бы обеспечил себя возможностью хранить файлы классов в различных подкаталогах. При первом вызове __autoload() сканирует все подкаталоги каталога classes, и выстраивает ассоциативный массив (className => filePath). Имена файлов могут иметь вид className.php или className-version.php (например, DBV-001.obsolete.php), последнее я сделал ради попытки как-то упорядочить свой бардак разных версий классов для разных проектов в едином репозитарии, с возможностью быстрого(?) и удобного(?) обновления сайтов, использующих одни и те же версии интерфейсов. В процессе сканирования функция проверяет уникальность имени класса.
Файл /_php/__autoload.php:
Всем привет!
Вот, решил поделиться.
В условия резкой нехватки namespaces, я хотя бы обеспечил себя возможностью хранить файлы классов в различных подкаталогах. При первом вызове __autoload() сканирует все подкаталоги каталога classes, и выстраивает ассоциативный массив (className => filePath). Имена файлов могут иметь вид className.php или className-version.php (например, DBV-001.obsolete.php), последнее я сделал ради попытки как-то упорядочить свой бардак разных версий классов для разных проектов в едином репозитарии, с возможностью быстрого(?) и удобного(?) обновления сайтов, использующих одни и те же версии интерфейсов. В процессе сканирования функция проверяет уникальность имени класса.
Файл /_php/__autoload.php:
PHP:
<?php
// (c) dimgel
// function __autoload() - class loader system function.
// Configuration:
$__autoload__classBase = dirname(__FILE__) . '/classes/';
function __autoload($className) {
global $__autoload__classBase;
static $classPaths = NULL; // Associative array (className => filePath).
if (!$classPaths) {
$classPaths = __autoload__scanPaths();
}
if (isset($classPaths[$className])) {
include_once($__autoload__classBase . $classPaths[$className]);
}
// If requested class is still not loaded after function exits,
// PHP triggers 'Class not found' fatal error.
}
// Internal. Recursive.
// Parameter $path is relative to _php/classes, e.g. "" for root, or "DBAPI/".
// Returns associative array (className => filePath) for given $path.
function __autoload__scanPaths($path = "") {
global $__autoload__classBase;
$result = array();
$absPath = $__autoload__classBase . $path;
// Strip last '/' from $absPath before calling scandir().
$fileNames = scandir(substr($absPath, 0, strlen($absPath)-1));
if ($fileNames) {
foreach($fileNames as $fileName) {
if (($fileName == '.') || ($fileName == '..')) {
continue;
}
if (is_dir($absPath . $fileName)) {
$subResult = __autoload__scanPaths($path . $fileName . "/");
foreach($subResult as $subClassName => $subFilePath) {
__autoload__addClass($result, $subClassName, $subFilePath);
}
}
else {
if (preg_match("/^([a-zA-Z0-9_]+)(-[0-9a-z\\.]+)?\\.php$/",
$fileName, $matches))
{
__autoload__addClass($result, $matches[1], $path . $fileName);
}
}
}
}
return $result;
}
// Internal. Adds class into result array, with className uniqueness checks.
function __autoload__addClass(&$result, $className, $filePath) {
if (!isset($result[$className])) {
$result[$className] = $filePath;
}
else {
throw new Exception("Classloader ambiguity for class '$className': files '" .
$result[$className] . "' and '$filePath'.");
}
}
?>