Hallo,
zur Zeit entwickel ich mein eigenes Framework. Dies dient überwiegend zum lernen, soll später aber auch als Grundlage für Projekte dienen.
Da ich soeben meine Autoload-Klasse fertiggestellt habe (bisschen Doku und Fehler abfangen fehlt noch) möchte ich diese gerne mal öffentlich zur Diskussion stellen.
Hier die Aufgaben die die Klasse erfüllen sollte:
- Soll die Dateien automatisch in bestimmten Ordnern suchen und einbinden
- Damit bei großen Ordner nicht jedesmal der Ordner durchsucht werden muss soll eine Cache Datei erstellt werden mit allen Klassenpfaden
- Der Cache soll sich automatisch aktualisieren wenn eine neu erstellte Klasse aufgerufen wird
Hier mal ein Beispiel wie man die Klasse benutzt:
So, dann sagt mal eure Meinung, egal ob positiv oder negativ.
zur Zeit entwickel ich mein eigenes Framework. Dies dient überwiegend zum lernen, soll später aber auch als Grundlage für Projekte dienen.
Da ich soeben meine Autoload-Klasse fertiggestellt habe (bisschen Doku und Fehler abfangen fehlt noch) möchte ich diese gerne mal öffentlich zur Diskussion stellen.
Hier die Aufgaben die die Klasse erfüllen sollte:
- Soll die Dateien automatisch in bestimmten Ordnern suchen und einbinden
- Damit bei großen Ordner nicht jedesmal der Ordner durchsucht werden muss soll eine Cache Datei erstellt werden mit allen Klassenpfaden
- Der Cache soll sich automatisch aktualisieren wenn eine neu erstellte Klasse aufgerufen wird
PHP-Code:
<?php
/*
* Verhindert das die Datei direkt aufgerufen werden kann
*/
if (defined('SCRIPT') === false) die('The file can not be called directly!');
final class Autoload
{
/**
* Beschreibung
*
* @static
*
* @var Autoload
*/
private static $objInstance;
/**
* Beschreibung
*
* @var string
*/
private $strExtension;
/**
* Beschreibung
*
* @var string
*/
private $strCachePath;
/**
* Beschreibung
*
* @var array
*/
private $arrRegister = array();
/**
* Beschreibung
*
* @var array
*/
private $arrClassRegister = array();
/**
* Autoload::__clone()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @return void
*/
private final function __clone() {}
/**
* Autoload::__construct()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @return void
*/
private final function __construct() {}
/**
* Autoload::getInstance()
*
* Beschreibung
*
* @author xxx
*
* @access public
*
* @static
* @final
*
* @return Autoload
*/
public static final function getInstance()
{
if (is_object(self :: $objInstance) === false)
{
self :: $objInstance = new Autoload();
}
return (self :: $objInstance);
}
/**
* Autpload::activate()
*
* Beschreibung
*
* @author xxx
*
* @access public
*
* @static
* @final
*
* @return void
*/
public function activate()
{
spl_autoload_register(array
(
$this,
'load'
));
}
/**
* Autpload::setExtension()
*
* Beschreibung
*
* @author xxx
*
* @access public
*
* @final
*
* @param string $strExtension
*
* @return void
*/
public final function setExtension($strExtension)
{
$this->strExtension = $strExtension;
spl_autoload_extensions($strExtension);
}
/**
* Autoload::setCacheFolder()
*
* Beschreibung
*
* @author xxx
*
* @access public
*
* @final
*
* @param string $strFolderPath
*
* @return boolean Bestätigung ob der Ordner gefunden werden konnte
*/
public final function setCacheFolder($strFolderPath, $blnCreateFolder = true)
{
/*
* Der Ordner ist nicht vorhanden und wird, wenn gewünscht, erstellt
*/
if (is_dir($strFolderPath) === false &&
$blnCreateFolder === true)
{
mkdir($strFolderPath, 0755, true);
}
/*
* Es konnte kein Ordner erstellt oder gefunden werden
*/
if (is_dir($strFolderPath) === false)
{
return (false);
}
$this->strCachePath = $strFolderPath;
return (true);
}
/**
* Autoload::register()
*
* Beschreibung
*
* @author xxx
*
* @access public
*
* @final
*
* @param string $strPath
* @param string $strCacheName
* @param boolean $blnForceLoad
*
* @return void
*/
public final function register($strPath, $strCacheName = null, $blnForceLoad = false)
{
/*
* Der übergebene Ordner existiert nicht
*/
if (is_dir($strPath) === false)
{
/*
* TODO: hier passiert noch was?
*/
}
/*
* Es wurde kein Cache-Name gewählt
*/
if (empty($strCacheName) === true)
{
$strCacheName = sha1($strCacheName);
}
/*
* Der Cache-Name enthält ungültige Zeichen
*/
if ((boolean) preg_match('#[^a-zA-Z0-9]#si', $strCacheName) === true)
{
/*
* TODO: hier passiert noch was?
*/
}
/*
* Der Pfad wird in der Registry gespeichert
*/
$this->arrRegister[$strCacheName] = $strPath;
/*
* Es gibt bereits eine Cache-Datei zu diesem Name (Cache-Verzeichnis muss gesetzt sein) sofern das neu schreiben des Caches nicht erzwungen wird
*/
if (empty($this->strCachePath) === false &&
file_exists($this->strCachePath . $strCacheName . '.cache.php') &&
$blnForceLoad === false)
{
return;
}
/*
* Alle Dateien mit der entsprechenden Dateiendung im Ordner ermitteln
*/
$objDirectory = new RecursiveDirectoryIterator($strPath);
$objIterator = new RecursiveIteratorIterator($objDirectory);
$objRegexIterator = new RegexIterator($objIterator, '#^.+' . preg_quote($this->strExtension, '#') . '$#si', RecursiveRegexIterator :: GET_MATCH);
/*
* Wenn der Cache aktiviert ist oder der Cache aktiviert und erzwungen wird
*/
if (empty($this->strCachePath) === false ||
(empty($this->strCachePath) === false && $blnForceLoad === true))
{
$this->writeCache($strCacheName, $objRegexIterator);
}
else
{
$this->writeClassRegisterFromIterator($objRegexIterator);
}
}
/**
* Autoload::loadCache()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @return void
*/
private final function loadCache()
{
/*
* Cache-Dateien ermitteln
*/
$objDirectory = new RecursiveDirectoryIterator($this->strCachePath);
$objIterator = new RecursiveIteratorIterator($objDirectory);
$objRegexIterator = new RegexIterator($objIterator, '#^.*' . preg_quote('.cache.php', '#') . '$#si', RecursiveRegexIterator :: GET_MATCH);
foreach ($objRegexIterator as $arrCacheFilePath)
{
if (file_exists($arrCacheFilePath[0]) === true)
{
include ($arrCacheFilePath[0]);
$arrCache = (array) unserialize($arrCache);
$this->writeClassRegisterFromCache($arrCache);
}
}
}
/**
* Autoload::writeCache()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @param string $strCacheName
* @param RegexIterator $objRegexIterator
*
* @return void
*/
private final function writeCache($strCacheName, RegexIterator $objRegexIterator)
{
$strCacheFile = $this->strCachePath . $strCacheName . '.cache.php';
$resHandle = fopen($strCacheFile, 'w+');
/*
* Es konnte kein Stream zur Datei aufgebaut werden
*/
if (is_resource($resHandle) === false)
{
/*
* TODO: hier passiert noch was?
*/
}
/*
* Die Datei kann nicht geschrieben werden
*/
if (is_writeable($strCacheFile) === false)
{
/*
* TODO: hier passiert noch was?
*/
}
$arrCache = array();
foreach ($objRegexIterator as $arrPath)
{
$strBasename = basename($arrPath[0]);
$strBasename = mb_substr($strBasename, 0, mb_stripos($strBasename, '.'));
$arrCache[$strBasename] = $arrPath[0];
}
fputs($resHandle, '<?php $arrCache = \'' .serialize($arrCache) . '\'; ?>');
fclose($resHandle);
}
/**
* Autoload::writeClassRegisterFromIterator()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @param RegexIterator $objRegexIterator
*
* @return void
*/
private final function writeClassRegisterFromIterator(RegexIterator $objRegexIterator)
{
foreach ($objRegexIterator as $arrPath)
{
/*
* Der Klassenname wird aus dem Pfad ermittelt
*/
$strBasename = basename($arrPath[0]);
$strBasename = mb_substr($strBasename, 0, mb_stripos($strBasename, '.'));
$this->arrClassRegister[$strBasename] = $arrPath[0];
}
}
/**
* Autoload::writeClassRegisterFromCache()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @param array $arrCache
*
* @return void
*/
private final function writeClassRegisterFromCache(array $arrCache)
{
foreach ($arrCache as $strClassName => $strClassPath)
{
$this->arrClassRegister[$strClassName] = $strClassPath;
}
}
/**
* Autoload::load()
*
* Beschreibung
*
* @author xxx
*
* @access private
*
* @final
*
* @param string $strClass
* @param boolean $blnRecursive
*
* @return boolean
*/
private final function load($strClass, $blnRecursive = false)
{
/*
* Wenn ein Cache-Verzeichnis gesetzt ist wird versucht der Cache zu laden
*/
if (empty($this->strCachePath) === false &&
empty($this->arrClassRegister) === true)
{
$this->loadCache();
}
/*
* Die Datei mit dem Klassennamen existiert
*/
if (empty($this->arrClassRegister[$strClass]) === false &&
file_exists($this->arrClassRegister[$strClass]) === true)
{
require_once ($this->arrClassRegister[$strClass]);
}
/*
* Es wird einmal versucht die Klasse zu ermitteln indem der Cache aktualisiert wird
*/
else if ($blnRecursive === false)
{
foreach ($this->arrRegister as $strCache => $strCachePath)
{
$this->register($strCachePath, $strCache, true);
}
return ($this->load($strClass, true));
}
/*
* Die Klasse existiert in dieser Datei nicht
*/
if (class_exists($strClass, false) === false)
{
trigger_error('Möp');
return (false);
}
return (true);
}
}
?>
PHP-Code:
$objAutoload = Autoload :: getInstance();
/*
* Dateiendung für den Autoloader festlegen
*/
$objAutoload->setExtension('.class.php');
/*
* Cacheverzeichnis für den Autloader festlegen
*/
$objAutoload->setCacheFolder(Registry :: get('CacheAutoloadPath'));
/*
* Verzeichnisse und Cachenamen für den Autoloader festlegen
*/
$objAutoload->register(Registry :: get('CoreLibraryPath'), 'CoreLibrary');
$objAutoload->register(Registry :: get('CoreInterfacePath'), 'CoreInterface');
$objAutoload->register(Registry :: get('ApplicationControllerPath'), 'ApplicationController');
/*
* Autoloader aktivieren
*/
$objAutoload->activate();
Kommentar