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
{
/**
* Use class map before paths
*
* @var bool
* @since 1.0.0
*/
public static bool $useClassMap = true;
/**
* Base paths for autoloading
*
@ -36,6 +44,18 @@ final class Autoloader
__DIR__ . '/../',
];
/**
* Base paths for autoloading
*
* @var string[]
* @since 1.0.0
*/
private static $classmap = [
'phpOMS' => __DIR__ . '/../',
'Modules' => __DIR__ . '/../',
'Models' => __DIR__ . '/../',
];
/**
* Constructor.
*
@ -60,6 +80,21 @@ final class Autoloader
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
*
@ -74,6 +109,20 @@ final class Autoloader
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
*
@ -114,6 +163,29 @@ final class Autoloader
$class = \ltrim($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) {
if (\is_file($file = $path . $class . '.php')) {
include_once $file;