From 58e38f3313c0413260bc7ab3a66fd9a10e00221e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 10 Oct 2022 17:47:52 +1100 Subject: [PATCH] Add Preloader --- preload.php | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 preload.php diff --git a/preload.php b/preload.php new file mode 100644 index 000000000000..6bf7ece52e44 --- /dev/null +++ b/preload.php @@ -0,0 +1,136 @@ +paths = $paths; + + // We'll use composer's classmap + // to easily find which classes to autoload, + // based on their filename + $classMap = require __DIR__ . '/vendor/composer/autoload_classmap.php'; + + $this->fileMap = array_flip($classMap); + } + + public function paths(string ...$paths): Preloader + { + $this->paths = array_merge( + $this->paths, + $paths + ); + + return $this; + } + + public function ignore(string ...$names): Preloader + { + $this->ignores = array_merge( + $this->ignores, + $names + ); + + return $this; + } + + public function load(): void + { + // We'll loop over all registered paths + // and load them one by one + foreach ($this->paths as $path) { + $this->loadPath(rtrim($path, '/')); + } + + $count = self::$count; + + echo "[Preloader] Preloaded {$count} classes" . PHP_EOL; + } + + private function loadPath(string $path): void + { + // If the current path is a directory, + // we'll load all files in it + if (is_dir($path)) { + $this->loadDir($path); + + return; + } + + // Otherwise we'll just load this one file + $this->loadFile($path); + } + + private function loadDir(string $path): void + { + $handle = opendir($path); + + // We'll loop over all files and directories + // in the current path, + // and load them one by one + while ($file = readdir($handle)) { + if (in_array($file, ['.', '..'])) { + continue; + } + + $this->loadPath("{$path}/{$file}"); + } + + closedir($handle); + } + + private function loadFile(string $path): void + { + // We resolve the classname from composer's autoload mapping + $class = $this->fileMap[$path] ?? null; + + // And use it to make sure the class shouldn't be ignored + if ($this->shouldIgnore($class)) { + return; + } + + // Finally we require the path, + // causing all its dependencies to be loaded as well + require_once($path); + + self::$count++; + + echo "[Preloader] Preloaded `{$class}`" . PHP_EOL; + } + + private function shouldIgnore(?string $name): bool + { + if ($name === null) { + return true; + } + + foreach ($this->ignores as $ignore) { + if (strpos($name, $ignore) === 0) { + return true; + } + } + + return false; + } +} + +(new Preloader()) + ->paths(__DIR__ . '/vendor/laravel') + ->ignore( + \Illuminate\Filesystem\Cache::class, + \Illuminate\Log\LogManager::class, + \Illuminate\Http\Testing\File::class, + \Illuminate\Http\UploadedFile::class, + \Illuminate\Support\Carbon::class, + ) + ->load(); \ No newline at end of file