prefix = trim( $prefix, '\\' ) . '\\'; $this->base_dir = rtrim( $base_dir, '/\\' ) . DIRECTORY_SEPARATOR; } /** * Creates a loader and registers it on the SPL autoload stack. * * @since 0.1.0 * * @param string $prefix Namespace prefix. * @param string $base_dir Base directory. * @return self */ public static function register( string $prefix, string $base_dir ): self { $loader = new self( $prefix, $base_dir ); spl_autoload_register( array( $loader, 'load_class' ) ); return $loader; } /** * Loads the file for a class, when it belongs to this loader's prefix. * * @since 0.1.0 * * @param string $class_name Fully qualified class name. * @return void */ public function load_class( string $class_name ): void { $file = $this->get_file_path( $class_name ); if ( null !== $file && is_readable( $file ) ) { require_once $file; } } /** * Resolves the expected file path for a class. * * @since 0.1.0 * * @param string $class_name Fully qualified class name. * @return string|null Absolute path, or null when the class is outside the prefix. */ public function get_file_path( string $class_name ): ?string { $class_name = ltrim( $class_name, '\\' ); if ( 0 !== strncmp( $this->prefix, $class_name, strlen( $this->prefix ) ) ) { return null; } $relative = substr( $class_name, strlen( $this->prefix ) ); return $this->base_dir . str_replace( '\\', DIRECTORY_SEPARATOR, $relative ) . '.php'; } }