Wikibase/History/Autoloading

From mediawiki.org

PHP’s autoloading mechanism allows for a class or interface to be loaded from a file automatically when it is first needed, rather than having to require_once the correct file to ensure that it has been loaded.

Over time, Wikibase has used the autoloading mechanism in different ways, mostly based on MediaWiki’s $wgAutoloadClasses map from class names to file names: initially (March 2012), entries were added to that array directly in the PHP entry points; later (April 2013), as these lists grew, they were split into separate files (repo/Wikibase.classes.php, client/WikibaseClient.classes.php, lib/WikibaseLib.classes.php). Then, the responsibility of maintaining these lists was moved to Composer’s autoload support, first using the classmap feature (January 2014), then (partially) the psr-4 feature (June 2014). Later still, in November 2017, we abandoned Composer and went back to $wgAutoloadClasses, using a script to generate autoload.php files which were included from the PHP entry points.

Throughout all this time, the association between namespaces and directories was on a best-effort basis: it was more or less recommended to place Lib classes under \Wikibase\Lib\, Client classes under \Wikibase\Client\, and so on, but this was never enforced, and there were always plenty of classes directly under Wikibase\ – after all, Composer and later our own generateAutoload.php could always figure out the final classmap by loading each file in the source code directories and inspecting its declared namespace. Under Composer, classes that did conform to the PSR-4 standard (according to the map from base namespace to directory name that was recorded in composer.json) were loaded using PSR-4, and the classmap was only used for classes that did not conform. However, at the time that we switched from Composer back to $wgAutoloadClasses, MediaWiki did not yet support PSR-4 autoloading, and so the (generated) classmap was used for all classes indiscriminately. MediaWiki gained support for PSR-4 autoloading afterwards (December 2017, released with MediaWiki 1.31 June 2018), but the required namespace/directory map could only be specified using the AutoloadNamespaces key of the extension.json file, and Wikibase did not use the new extension registration system at the time. (There is no corresponding $wgAutoloadNamespaces that we could have set in the PHP entry points.)

Finally, in May 2019 we started using extension registration, moving settings from the PHP entry points to the JSON files bit by bit. This allowed us to start specifying AutoloadNamespaces as well, and generateAutoload.php was adjusted so that it would not emit $wgAutoloadClasses entries for classes that could be loaded via AutoloadNamespaces. Initially, a structure test in MediaWiki would not permit us to register any autoload namespaces containing files that did not conform to PSR-4, and so we could only register namespaces for autoloading which were already fully converted; we would fix subnamespaces to conform to PSR-4 and add then add them to AutoloadNamespaces, one at a time. In March 2020, the structure test was relaxed to no longer require “perfect” namespaces, and so we were able to add wider mappings like "Wikibase\\Repo\\": "repo/includes/" to the JSON files. At that point, the autoload.php files became effectively work lists, containing all the classes that still had to be moved to the correct namespace.

The move of all Wikibase classes to the correct namespace (according to their directory, which was usually more accurate) was completed in June 2020. The autoload.php files and the generateAutoload.php script to generate them were removed, and there was much rejoicing in the land. There is no mechanism to load non-compliant files, so the risk of accidentally introducing new classes that do not conform to PSR-4 is negligible (you’d notice the error as soon as you tried to use the class).