PHP Surface Test Four implementation autoload

Source: Internet
Author: User
Tags autoload autoloader yii

This article introduces the content of the PHP surface of the question four implementation autoload, has a certain reference value, now share to everyone, the need for friends can refer to

The YII framework declares its own class-loading method to be efficient and a true "time-loaded", and where is it especially? Today, we studied the source code, and found that it was added a layer of "path cache"at the coding level.

Automatic loading principle of YII2

We know that to implement our own AutoLoad method, we need to use spl_autoload_register() a function to register a AutoLoad method , and this method of Yii registration is YiiBase::autoload() to explain the logic of this method later. In addition, Yii is generally used Yii::import($pathAlias, $forceInclude=false) to load the corresponding class (this method is called directly YiiBase::import() ), this method YiiBase::autoload() can be implemented with "time loading".

first say the approximate logic of import:
1, check self::$_imports array for the existence of the corresponding $pathAlias , If a description has already been loaded, return the class name or directory name directly, or proceed to step 2nd,
2, get the actual pathname based on the path alias, and whether the last part of the path alias is "*" You can know whether the path alias to be loaded is a file, if it is a file, go to 3rd step, otherwise go to 4th step,
3, if $forceInclude is true, immediately require the file, and in $_ Add an item in the Imports array $alias = = $className; otherwise cache an entry in the array $classMap $className = Realpath ;
4, for the path, the path is cached in the array $_includepaths , and a $_imports array is added $alias = = $realPath ;
5, end.
because $ forceinclude is false by default, import does not immediately load the corresponding class until it is used, and this is the work of yiibase::autoload .

The approximate logic of AutoLoad:
1, check whether the class name is cached in $classMap or $_coreClasses array, if it is directly require the corresponding file path, $_coreClasses is the framework's own class mapping table; otherwise go to the 2nd step;
2, detection is YiiBase::$enableIncludePath false, if it is the 3rd step, otherwise directly include($className . '.php')
3, iterate the $includePaths array, the directory name stitching on the class name, check whether it is a valid PHP file, if it is the include, and then jump out of the loop
4, the end.
Note that the document states that if you want to use it with other class libraries, you must set $enableIncludePath false so that the Yii::autoload() methods of other class libraries will have an opportunity to execute when they fail autoload .
$enableIncludePathwhether to rely on PHP to include the path to the auto-load class file. The default is true. If your hosting environment does not allow you to change the PHP include path, it can be set to False, or you want to add another autoloader to the default Yii autoloader.

Official Description Document

In Yii, all classes, interfaces, and traits can be automatically loaded before a call by using the automatic loading mechanism of the class. Yii uses the class automatic loading mechanism of PHP to realize the positioning and import of class efficiently, which is compatible with PSR-4 standard. In Yii, classes are loaded only when they are called, especially the core class, which is positioned very fast, which is an important embodiment of Yii's high performance.

Implementation of automatic loading mechanism
The Yii class automatically loads, relies on PHP's Spl_autoload_register (), registers a self-loading function (autoloader), and inserts it to the top of the auto-load function stack, ensuring that Yii's autoloader is called first.

The introduction of this mechanism for automatic class loading starts with the entry file index.php:

<?phpdefined (' yii_debug ') or define (' Yii_debug ', false);d efined (' yii_env ') or define (' yii_env ', ' prod ');// This is a third-party Autoloaderrequire (__dir__. '/.. /.. /vendor/autoload.php ');//This is the autoloader of Yii, put it on the last side and make sure that the autoloader it inserts is placed at the front require (__dir__. '/.. /.. /vendor/yiisoft/yii2/yii.php '), or//there should be no autoloader behind require (__dir__. '/.. /.. /common/config/aliases.php '); $config = Yii\helpers\arrayhelper::merge (    require (__dir__. '/.. /.. /common/config/main.php '),    require (__dir__. '/.. /.. /common/config/main-local.php '),    require (__dir__. '/.. /config/main.php '),    require (__dir__. '/.. /config/main-local.php '); $application = new Yii\web\application ($config); $application->run ();

The main aspect of this document is the sequence of autoloader implemented by third-party autoloader and Yii. No matter how the third-party code is used spl_autoload_register() to register its own autoloader, as long as Yii's code is on the last side, it can be ensured that it can insert its own autoloader into the front of the entire Autoloder stack, and is called first when needed.

Next, look at how Yii invokes spl_autoload_register() the registration autoloader, which depends on what happens in yii.php:

<?phprequire (__dir__. '/baseyii.php '); class Yii extends \yii\baseyii{}//focus on this spl_autoload_registerspl_autoload_register ([' Yii ', ' AutoLoad '], true, true);//The following statement reads a mapping table Yii:: $classMap = include (__dir__. '/classes.php '); Yii:: $container = new Yii\di\container;

This code, called spl_autoload_register(['Yii', 'autoload', true, true]) , will be inserted at the Yii::autoload() autoloader front of the stack. The classes.php is read into and Yii::$classMap A mapping table is saved.

In the above code, the Yii class is no code inside, and Baseyii::autoload () is not overloaded, so this spl_autoload_register () will actually be BaseYii::autoload() registered as autoloader . If you want to implement your own autoloader, you can overload it in the code of the Yii class autoload() .

After the call spl_autoload_register() is autoloader registered, Yii saves the calsses.php file as a mapping table Yii::$classMap . This mapping table holds a series of mappings between the class name and the PHP file in which it resides, such as:

return [  ' yii\base\action ' = Yii2_path. '/base/action.php ',  ' yii\base\actionevent ' = Yii2_path. '/base/actionevent.php ',  ...  ' Yii\widgets\pjaxasset ' = Yii2_path. '/widgets/pjaxasset.php ',  ' yii\widgets\spaceless ' = Yii2_path. '/widgets/spaceless.php ',];

This mapping table takes the class name as the key, the actual class file as the value, all the core classes of Yii have been written to this classes.php file, so the core class loading is the most convenient and fastest. Now, take a look at this key, sir.BaseYii::autoload()

public static function AutoLoad ($className) {    if (isset (static:: $classMap [$className])) {            $classFile = static: : $classMap [$className];        if ($classFile [0] = = = = ' @ ') {            $classFile = Static::getalias ($classFile);        }    } elseif (Strpos ($className, ' \ \ ') !== false) {            $classFile = Static::getalias (' @ '. Str_replace (' \ \ ', '/',            $className). '. php ', false);            if ($classFile = = = False | |!is_file ($classFile)) {            return;        }    } else {            return;    }        Include ($classFile);        if (Yii_debug &&!class_exists ($className, False) &&        !interface_exists ($className, False) & &!trait_exists ($className,        false)) {                throw new Unknownclassexception (                "Unable to find ' $ ClassName ' in file: $classFile. Namespace missing? "        );}    }

From this code to see how the Yii class automatic loading mechanism operation principle:

Check $classMap[$className] to see if the location information of the quasi-loaded class is already in the mapping table;

If there is, look at this location information is not a path alias, that is, not at the beginning of the @, if so, the path alias is resolved to the actual path. If the location information in the mapping table is not a path alias, the path is used as the location of the class file. The full path of the class file is saved in the $classFile;

If $classMap[$className] there is no information for this class, then see if the class name contains \, if not, it is a class name that does not conform to the specification, Autoloader returns directly. PHP will attempt to load with other autoloader that are already registered. If there is \, consider the class name to conform to the specification and convert it into a path form. That is, all the \ uses/substitutions, plus the. php suffix.

The replaced class name, plus the @ prefix, is parsed as a path alias. From the parsing process of the alias we know that if the root alias does not exist, an exception will be thrown. Therefore, the name of the class must begin with a valid root alias:

Valid class name because @yii is an already predefined alias use yii\base\application;//Invalid class name, because there is no @foo or @foo/bar root alias, the use foo\bar\someclass should be defined in advance;

Use PHP's include () to load the class file in to implement the class's loading.

From its operating principle, the quickest way to find a class is to use a mapping table. Secondly, all of the class names in Yii need to register valid root aliases In addition to conforming to the specifications.

Using the automatic loading mechanism
In the portal script, in addition to Yii's own autoloader, there is a third-party autoloader:

Require (__dir__. '/.. /.. /vendor/autoload.php ');

This is actually the autoloader provided by composer. Yii uses composer as the package dependency manager, so it is recommended to retain the autoloader of composer, even though Yii autoloader can automatically load third-party libraries, extensions, etc. that use composer installations, and is more efficient. But considering that after all, they are installed, they also have a set of their own special rules, from the maintenance, compatibility, extensibility to consider, it is recommended to retain the composer Autoloader.

If there are other autoloader, be sure to complete the registration before Yii's autoloader registration to ensure that Yii autoloader is always the first to be called.

If you have your own autoloader, you can also not install Yii Autoloaer, but this may not be able to have yii efficient, and also need to follow a set of similar class naming and loading rules. As far as personal experience is concerned, Yii's autoloader is fully sufficient, and there is no need to reinvent the wheel.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.