MediaWiki master
AutoLoader.php
Go to the documentation of this file.
1<?php
7// NO_AUTOLOAD -- file scope code, can't load self
8
13require_once __DIR__ . '/../autoload.php';
14
40
44 private static $psr4Namespaces = [];
45
49 private static $classFiles = [];
50
59 public static function registerNamespaces( array $dirs ): void {
60 self::$psr4Namespaces += $dirs;
61 }
62
69 public static function registerClasses( array $files ): void {
70 self::$classFiles += $files;
71 }
72
89 public static function loadFile( string $file ): void {
90 require_once $file;
91 }
92
102 public static function loadFiles( array $files ): void {
103 foreach ( $files as $f ) {
104 self::loadFile( $f );
105 }
106 }
107
114 public static function find( $className ): ?string {
116
117 // NOTE: $wgAutoloadClasses is supported for compatibility with old-style extension
118 // registration files.
119
120 $filename = $wgAutoloadLocalClasses[$className] ??
121 self::$classFiles[$className] ??
122 $wgAutoloadClasses[$className] ??
123 false;
124
125 if ( !$filename && str_contains( $className, '\\' ) ) {
126 // This class is namespaced, so look in the namespace map
127 $prefix = $className;
128 // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
129 while ( ( $pos = strrpos( $prefix, '\\' ) ) !== false ) {
130 // Check to see if this namespace prefix is in the map
131 $prefix = substr( $className, 0, $pos + 1 );
132 if ( isset( self::$psr4Namespaces[$prefix] ) ) {
133 $relativeClass = substr( $className, $pos + 1 );
134 // Build the expected filename, and see if it exists
135 $file = self::$psr4Namespaces[$prefix] .
136 strtr( $relativeClass, '\\', '/' ) .
137 '.php';
138 if ( is_file( $file ) ) {
139 $filename = $file;
140 break;
141 }
142 }
143
144 // Remove trailing separator for next iteration
145 $prefix = rtrim( $prefix, '\\' );
146 }
147 }
148
149 if ( !$filename ) {
150 // Class not found; let the next autoloader try to find it
151 return null;
152 }
153
154 // Make an absolute path, this improves performance by avoiding some stat calls
155 // Optimisation: use string offset access instead of substr
156 if ( $filename[0] !== '/' && $filename[1] !== ':' ) {
157 $filename = __DIR__ . '/../' . $filename;
158 }
159
160 return $filename;
161 }
162
168 public static function autoload( $className ) {
169 $filename = self::find( $className );
170
171 if ( $filename !== null ) {
172 require_once $filename;
173 }
174 }
175
177 private static function assertTesting( string $method ): void {
178 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
179 throw new LogicException( "$method is not supported outside phpunit tests!" );
180 }
181 }
182
188 public static function getClassFiles(): array {
190
191 self::assertTesting( __METHOD__ );
192
193 // NOTE: ensure the order of preference is the same as used by find().
194 return array_merge(
196 self::$classFiles,
198 );
199 }
200
206 public static function getNamespaceDirectories(): array {
207 self::assertTesting( __METHOD__ );
208 return self::$psr4Namespaces;
209 }
210
218 public static function getState(): array {
219 self::assertTesting( __METHOD__ );
220 return [
221 'classFiles' => self::$classFiles,
222 'psr4Namespaces' => self::$psr4Namespaces,
223 ];
224 }
225
234 public static function restoreState( $state ): void {
235 self::assertTesting( __METHOD__ );
236
237 self::$classFiles = $state['classFiles'];
238 self::$psr4Namespaces = $state['psr4Namespaces'];
239 }
240
241}
242
243spl_autoload_register( AutoLoader::autoload( ... ) );
244
245// Load composer's autoloader if present
246if ( is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
247 require_once __DIR__ . '/../vendor/autoload.php';
248} elseif ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) {
249 die( __DIR__ . '/../vendor/autoload.php exists but is not readable' );
250}
$wgAutoloadClasses
Definition Setup.php:141
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:69
global $wgAutoloadLocalClasses
Definition autoload.php:4
This initializes autoloading for MediaWiki core, extensions, and vendored libraries.
static registerClasses(array $files)
Register a file to load the given class from.
static loadFiles(array $files)
Batch version of loadFile()
static restoreState( $state)
Returns an array representing the internal state of Autoloader, so it can be remembered and later res...
static getNamespaceDirectories()
Returns a map of namespace names to directories, per PSR4.
static registerNamespaces(array $dirs)
Register a directory to load the classes of a given namespace from, per PSR4.
static find( $className)
Find the file containing the given class.
static getState()
Returns an array representing the internal state of Autoloader, so it can be remembered and later res...
static getClassFiles()
Returns a map of class names to file paths for testing.
static loadFile(string $file)
Load a file that declares classes, functions, or constants.
static autoload( $className)
autoload - take a class name and attempt to load it