From: Michael M Slusarz Date: Tue, 4 Aug 2009 23:23:52 +0000 (-0600) Subject: Optimize autoloading. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=7ac451af71d142c5de7d2b17edc3a7c01ac0eef6;p=horde.git Optimize autoloading. Run through class patterns first before trying to use include paths. This prevents us from having to add applications to the include path, so PEAR/external libs shouldn't try to load libraries that have the same basenames as an application library. --- diff --git a/framework/Autoloader/lib/Horde/Autoloader.php b/framework/Autoloader/lib/Horde/Autoloader.php index a4f2e347c..8df00d48d 100644 --- a/framework/Autoloader/lib/Horde/Autoloader.php +++ b/framework/Autoloader/lib/Horde/Autoloader.php @@ -13,9 +13,7 @@ class Horde_Autoloader * * @var array */ - protected static $_classPatterns = array( - array('/^Horde_/i', 'Horde/'), - ); + protected static $_classPatterns = array(); /** * The include path cache. @@ -38,38 +36,44 @@ class Horde_Autoloader */ public static function loadClass($class) { + /* Search in class patterns first. */ foreach (self::$_classPatterns as $classPattern) { list($pattern, $replace) = $classPattern; - $file = $class; if (!is_null($replace) && - preg_match($pattern, $file, $matches, PREG_OFFSET_CAPTURE)) { - $file_path = str_replace(array('::', '_'), '/', substr($file, 0, $matches[0][1])) . - $replace . - str_replace(array('::', '_'), '/', substr($file, $matches[0][1] + strlen($matches[0][0]))); - } else { - $file_path = str_replace(array('::', '_'), '/', $file); - } - - if (!is_null($replace) || preg_match($pattern, $file)) { - $err_mask = E_ALL ^ E_WARNING; - if (defined('E_DEPRECATED')) { - $err_mask = $err_mask ^ E_DEPRECATED; + preg_match($pattern, $class, $matches, PREG_OFFSET_CAPTURE)) { + if (strcasecmp($matches[0][0], $class) === 0) { + $file_path = $replace . '/' . $class; + } else { + $file_path = str_replace(array('::', '_'), '/', substr($class, 0, $matches[0][1])) . + $replace . + str_replace(array('::', '_'), '/', substr($class, $matches[0][1] + strlen($matches[0][0]))); } - $oldErrorReporting = error_reporting($err_mask); - //@TODO: This may be a neccessary evil since any external - // library that triggers an Autoloader for a class that is named - // the same as any file that is currently in the include_path - // (which includes all lib/* files for applications currently on - // the stack) will cause that file to possibly load that file - // more then once. This causes fatal Cannon redeclare class errors. - $included = include_once $file_path . '.php'; - error_reporting($oldErrorReporting); - if ($included) { + + if (self::_loadClass($file_path)) { return true; } } } + + /* Do a final search in the include path. */ + $file_path = str_replace(array('::', '_'), '/', $class); + return self::_loadClass($file_path); + } + + /** + * TODO + */ + protected static function _loadClass($file_path) + { + $err_mask = E_ALL ^ E_WARNING; + if (defined('E_DEPRECATED')) { + $err_mask = $err_mask ^ E_DEPRECATED; + } + $oldErrorReporting = error_reporting($err_mask); + $included = include_once $file_path . '.php'; + error_reporting($oldErrorReporting); + return $included; } /** @@ -109,7 +113,13 @@ class Horde_Autoloader * Add a new class pattern. * * @param string $pattern The class pattern to add. - * @param string $replace The substitution pattern. + * @param string $replace The substitution pattern. All '_' and '::' + * strings in a classname will be converted to + * directory separators. If the entire pattern + * is matched, the matched text will be appended + * to the replacement string (allows for a single + * base class file to live within the include + * directory). */ public static function addClassPattern($pattern, $replace = null) { diff --git a/framework/Core/lib/Horde/Registry.php b/framework/Core/lib/Horde/Registry.php index bc4b6bdd7..2f8c082fd 100644 --- a/framework/Core/lib/Horde/Registry.php +++ b/framework/Core/lib/Horde/Registry.php @@ -874,8 +874,7 @@ class Horde_Registry * be done here because it is possible to try to load app-specific * libraries from other applications. */ $app_lib = $this->get('fileroot', $app) . '/lib'; - Horde_Autoloader::addClassPath($app_lib); - Horde_Autoloader::addClassPattern('/^' . $app . '_/i', $app_lib); + Horde_Autoloader::addClassPattern('/^' . $app . '(?:$|_)/i', $app_lib); /* Chicken and egg problem: the language environment has to be loaded * before loading the configuration file, because it might contain