improve autoloading performance with class map

This commit is contained in:
Dennis Eichhorn 2023-09-29 02:21:34 +00:00
parent b969bc927c
commit 5d66591a55

View File

@ -26,6 +26,14 @@ namespace phpOMS;
*/ */
final class Autoloader final class Autoloader
{ {
/**
* Use class map before paths
*
* @var bool
* @since 1.0.0
*/
public static bool $useClassMap = true;
/** /**
* Base paths for autoloading * Base paths for autoloading
* *
@ -36,6 +44,18 @@ final class Autoloader
__DIR__ . '/../', __DIR__ . '/../',
]; ];
/**
* Base paths for autoloading
*
* @var string[]
* @since 1.0.0
*/
private static $classmap = [
'phpOMS' => __DIR__ . '/../',
'Modules' => __DIR__ . '/../',
'Models' => __DIR__ . '/../',
];
/** /**
* Constructor. * Constructor.
* *
@ -60,6 +80,21 @@ final class Autoloader
self::$paths[] = \rtrim($path, '/\\') . '/'; self::$paths[] = \rtrim($path, '/\\') . '/';
} }
/**
* Add base path for autoloading
*
* @param string $amp Namespace start
* @param string $path Absolute base path with / at the end
*
* @return void
*
* @since 1.0.0
*/
public static function addClassMap(string $map, string $path) : void
{
self::$classmap[$map] = \rtrim($path, '/\\') . '/';
}
/** /**
* Check if a path is already in the path list * Check if a path is already in the path list
* *
@ -74,6 +109,20 @@ final class Autoloader
return \in_array(\rtrim($path, '/\\') . '/', self::$paths); return \in_array(\rtrim($path, '/\\') . '/', self::$paths);
} }
/**
* Check if a namespace map is already in the classpath list
*
* @param string $amp Namespace start
*
* @return bool
*
* @since 1.0.0
*/
public static function inClassMap(string $map) : bool
{
return isset(self::$classmap[$map]);
}
/** /**
* Find include paths for class * Find include paths for class
* *
@ -114,6 +163,29 @@ final class Autoloader
$class = \ltrim($class, '\\'); $class = \ltrim($class, '\\');
$class = \strtr($class, '_\\', '//'); $class = \strtr($class, '_\\', '//');
if (self::$useClassMap) {
$nspacePos = \strpos($class, '/');
$subclass = $nspacePos === false ? '' : \substr($class, 0, $nspacePos);
if (isset(self::$classmap[$subclass])) {
include_once self::$classmap[$subclass] . $class . '.php';
return;
}
/*
if (!isset($valid[$subclass])) {
foreach (self::$classmap as $map => $path) {
if (\str_starts_with($class, $map)) {
include_once $path . $class . '.php';
return;
}
}
}
*/
}
foreach (self::$paths as $path) { foreach (self::$paths as $path) {
if (\is_file($file = $path . $class . '.php')) { if (\is_file($file = $path . $class . '.php')) {
include_once $file; include_once $file;