getMessage()); exit(); } } //examine the stack to get the calling file $stacktrace = debug_backtrace(); if (array_key_exists($depth, $stacktrace) && array_key_exists('file', $stacktrace[$depth])) { $calling_file = $stacktrace[$depth]['file']; if (static::$debug) { consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_SYSTEM, 'Registering ' . realpath(Autoloader::$base_dir . '/' . $directory) . ' to ' . $calling_file); } //register the directory to the calling file Autoloader::$file_registry[$calling_file][] = $directory; } //register the directory globally if(!in_array($directory, Autoloader::$registry)) Autoloader::$registry[] = $directory; } public static function find_class_definition(string $directory, $class_name) : ?string { foreach(Autoloader::$file_types as $type) { //$class_path = realpath(Autoloader::$base_dir.'/'.$directory.'/'.$class_name.$type); $class_path = realpath($directory . '/' . $class_name . $type); if (static::$debug) { consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __LINE__)); consoleLog(static::$res, CON_SYSTEM, 'Checking for class ' . $class_name . ' in directory: ' . $directory); consoleLog(static::$res, CON_SYSTEM, 'Class Path: (' . $class_path . ')'); } if (file_exists($class_path)) { if (static::$debug) { consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __LINE__)); consoleLog(static::$res, CON_SYSTEM, 'Found class ' . $class_name); } return $class_path; } } return null; } public static function load(string $class_name, int $depth = 1) :void { if(!Autoloader::$initialized) Autoloader::initialize(); //get the context file we called from $stacktrace = debug_backtrace(); @$calling_file = $stacktrace[$depth]['file']; //attempt to load from the local context $checked_dirs = array(); if(array_key_exists($calling_file, Autoloader::$file_registry) && is_array(Autoloader::$file_registry[$calling_file])) { foreach(Autoloader::$file_registry[$calling_file] as $directory) { if (static::$debug) { consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_SYSTEM, 'Local Seek [' . $directory . ']'); } try { $definition = Autoloader::find_class_definition($directory, $class_name); } catch (TypeError $t) { if (static::$debug) consoleLog(static::$res, CON_ERROR, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_ERROR, $t->getMessage()); exit(); } if (!is_null($definition)) { try { /** @noinspection PhpIncludeInspection */ require_once($definition); } catch (Throwable $t) { if (static::$debug) consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_ERROR, $t->getMessage()); exit(); } return; } $checked_dirs[] = $directory; } } //TODO: chain scopes so you have proper scope inheritance (not just local to the calling file) // foreach depth we trim one link off the stack, then we walk through the stack. looking for scope // attempt to load from the global context foreach(Autoloader::$registry as $directory) { if (static::$debug) consoleLog(static::$res, CON_SYSTEM,'Global Seek ['.$directory.']'); try { $definition = Autoloader::find_class_definition($directory, $class_name); if (!is_null($definition)) { /** @noinspection PhpIncludeInspection */ require_once($definition); return; } } catch (TypeError $t) { if (static::$debug) consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_ERROR, $t->getMessage()); return; } } // uh oh, we can't find the class, we're going to have to return a clean crash-dummy, so we can catch the error consoleLog(static::$res, CON_ERROR, 'Could not find the class: ' . $directory . SLASH . $class_name . ' Creating a dummy.'); try { Autoloader::load_text(Autoloader::create_crash_dummy($class_name), $class_name); } catch (TypeError $t) { if (static::$debug) consoleLog(static::$res, CON_SYSTEM, sprintf(INFO_LOC, basename(__METHOD__), __FILE__)); consoleLog(static::$res, CON_ERROR, $t->getMessage()); } } public static function load_text(string $class_text, ?string $class=null, ?string $namespace=null) :void { try { eval('?>' . $class_text . ''.$class_with_package_text.'getMessage()); consoleLog(static::$res, CON_ERROR, $class_text); } } } public static function create_crash_dummy(string $class_name): string { return ''; } }