/Feeds/Feed_Fetcher.php`. */ final class Autoloader { /** * Namespace prefix handled by this loader, with a trailing separator. * * @var string */ private string $prefix; /** * Directory the namespace prefix maps to, with a trailing slash. * * @var string */ private string $base_dir; /** * Constructor. * * @param string $prefix Root namespace, e.g. `PulseCast`. * @param string $base_dir Directory containing the root namespace's files. */ public function __construct( string $prefix, string $base_dir ) { $this->prefix = trim( $prefix, '\\' ) . '\\'; $this->base_dir = rtrim( $base_dir, '/\\' ) . '/'; } /** * Registers the loader with PHP. */ public function register(): void { spl_autoload_register( array( $this, 'load' ) ); } /** * Loads the file for a class, if it belongs to this namespace and exists. * * @param string $class_name Fully qualified class name. */ public function load( string $class_name ): void { if ( ! str_starts_with( $class_name, $this->prefix ) ) { return; } $relative = substr( $class_name, strlen( $this->prefix ) ); // Valid class names are word characters joined by namespace separators; refuse anything else. if ( 1 !== preg_match( '/^\w+(?:\\\\\w+)*$/', $relative ) ) { return; } $file = $this->base_dir . str_replace( '\\', '/', $relative ) . '.php'; if ( is_file( $file ) ) { require_once $file; } } }