yii2初始化详解 – 深究yii2 autoload机制

yii2初始化详解 – 深究yii2 autoload机制

yii2采用的基于namespace的autoload机制,我们从初始化来参看yii2的autoload机制的整个过程,详解yii的初始化过程

1.在入口文件index.php我们可以看到代码:

  1. require(__DIR__ . '/../../vendor/autoload.php');

2.我们打开这个文件:

  1. <?php
  2. // autoload.php @generated by Composer
  3. require_once __DIR__ . '/composer' . '/autoload_real.php';
  4. return ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88::getLoader();

可以看到加载了文件/vendor/composer/autoload_real.php,打开这个文件,我们可以发现,里面定义了一个php的class类:

ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88

也就是调用了这个类的getLoader()方法。

3.找到这个方法getLoader()方法:下面是所有的代码:

  1. <?php
  2. // autoload_real.php @generated by Composer
  3. class ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88
  4. {
  5. private static $loader;
  6. public static function loadClassLoader($class)
  7. {
  8. if ('Composer\Autoload\ClassLoader' === $class) {
  9. require __DIR__ . '/ClassLoader.php';
  10. }
  11. }
  12. public static function getLoader()
  13. {
  14. if (null !== self::$loader) {
  15. return self::$loader;
  16. }
  17. spl_autoload_register(array('ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88', 'loadClassLoader'), true, true);
  18. self::$loader = $loader = new \Composer\Autoload\ClassLoader();
  19. spl_autoload_unregister(array('ComposerAutoloaderInit90def245ed1c6f870abec3fefcc03f88', 'loadClassLoader'));
  20. $map = require __DIR__ . '/autoload_namespaces.php';
  21. foreach ($map as $namespace => $path) {
  22. $loader->set($namespace, $path);
  23. }
  24. $map = require __DIR__ . '/autoload_psr4.php';
  25. foreach ($map as $namespace => $path) {
  26. $loader->setPsr4($namespace, $path);
  27. }
  28. $classMap = require __DIR__ . '/autoload_classmap.php';
  29. if ($classMap) {
  30. $loader->addClassMap($classMap);
  31. }
  32. $loader->register(true);
  33. $includeFiles = require __DIR__ . '/autoload_files.php';
  34. foreach ($includeFiles as $file) {
  35. composerRequire90def245ed1c6f870abec3fefcc03f88($file);
  36. }
  37. return $loader;
  38. }
  39. }
  40. function composerRequire90def245ed1c6f870abec3fefcc03f88($file)
  41. {
  42. require $file;
  43. }

首先我们看到的是spl_autoload_register这个方法,这个方法的作用是,在找不到类的情况下,通过这个函数定义的类方法去找,通过传递的参数,返回加载的类的路径。也就是说,当找不到类的时候,就通过这个方法找:

  1. public static function loadClassLoader($class)
  2. {
  3. if ('Composer\Autoload\ClassLoader' === $class) {
  4. require __DIR__ . '/ClassLoader.php';
  5. }
  6. }

因此这段代码  self::$loader = $loader = new \Composer\Autoload\ClassLoader();

加载的文件是vendor/composer/ClassLoader.php

4.然后通过这个类的方法,加载很多初始路径:

  1. $map = require __DIR__ . '/autoload_namespaces.php';
  2. foreach ($map as $namespace => $path) {
  3. $loader->set($namespace, $path);
  4. }
  5. $map = require __DIR__ . '/autoload_psr4.php';
  6. foreach ($map as $namespace => $path) {
  7. $loader->setPsr4($namespace, $path);
  8. }
  9. $classMap = require __DIR__ . '/autoload_classmap.php';
  10. if ($classMap) {
  11. $loader->addClassMap($classMap);
  12. }
  13. $loader->register(true);
  14. $includeFiles = require __DIR__ . '/autoload_files.php';
  15. foreach ($includeFiles as $file) {
  16. composerRequire90def245ed1c6f870abec3fefcc03f88($file);
  17. }
  18. return $loader;

4.1通过set  setPsr4  addClassMap等方法进行namespace路径初始化。 这个对应的文件是/autoload_psr4.php , 这个文件里面是对yii2的插件的namespace的定义:

  1. <?php
  2. // autoload_psr4.php @generated by Composer
  3. $vendorDir = dirname(dirname(__FILE__));
  4. $baseDir = dirname($vendorDir);
  5. return array(
  6. 'yii\\swiftmailer\\' => array($vendorDir . '/yiisoft/yii2-swiftmailer'),
  7. 'yii\\redis\\' => array($vendorDir . '/yiisoft/yii2-redis'),
  8. 'yii\\gii\\' => array($vendorDir . '/yiisoft/yii2-gii'),
  9. 'yii\\faker\\' => array($vendorDir . '/yiisoft/yii2-faker'),
  10. 'yii\\debug\\' => array($vendorDir . '/yiisoft/yii2-debug'),
  11. 'yii\\composer\\' => array($vendorDir . '/yiisoft/yii2-composer'),
  12. 'yii\\codeception\\' => array($vendorDir . '/yiisoft/yii2-codeception'),
  13. 'yii\\bootstrap\\' => array($vendorDir . '/yiisoft/yii2-bootstrap'),
  14. 'yii\\' => array($vendorDir . '/yiisoft/yii2'),
  15. 'fecadmin\\' => array($vendorDir . '/fancyecommerce/fec_admin'),
  16. 'fec\\' => array($vendorDir . '/fancyecommerce/fec'),
  17. 'cebe\\markdown\\' => array($vendorDir . '/cebe/markdown'),
  18. 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
  19. );

定义各个插件的根路径。

4.2autoload_classmap.php 这个目前为空,没有细致研究具体内部的存放

4.3/autoload_files.php

  1. <?php
  2. // autoload_files.php @generated by Composer
  3. $vendorDir = dirname(dirname(__FILE__));
  4. $baseDir = dirname($vendorDir);
  5. return array(
  6. '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
  7. '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
  8. );

4.4  这是非yii2插件的包库 autoload_namespaces.php

  1. <?php
  2. // autoload_namespaces.php @generated by Composer
  3. $vendorDir = dirname(dirname(__FILE__));
  4. $baseDir = dirname($vendorDir);
  5. return array(
  6. 'PHPExcel' => array($vendorDir . '/phpoffice/phpexcel/Classes'),
  7. 'Imagine' => array($vendorDir . '/imagine/imagine/lib'),
  8. 'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
  9. 'Diff' => array($vendorDir . '/phpspec/php-diff/lib'),
  10. );

譬如我的yii2 – fec 插件中加入的PHPExcel 和Imagine 库包,就会在这里被标注namespace的对应关系。

对于composer安装的库包,有的是include的方式加入的,譬如Excel,安装库包后,不需要再程序中require,包管理器在autoload_namespaces.php  会加入路径,自动加载进来。

还有的是基于namespaces的,譬如Imagine。

5. 通过上面的配置,去找到对应文件路径,加载文件。

也就是说,对于 https://packagist.org/ 这里的php的库包,我们都可以通过composer加载到我们的系统中,在线安装。

譬如:我的fec插件的   composer.json的配置。

  1. "require": {
  2. "php": ">=5.4.0",
  3. "yiisoft/yii2": ">=2.0.6",
  4. "imagine/imagine": "0.5.*",
  5. "phpoffice/phpexcel": "1.8.*"
  6. },
  7. "autoload": {
  8. "psr-4": {
  9. "fec\\": ""
  10. }
  11. },

其中require代表的需要下载的包

autoload  psr-4 里面添加了信息后,会在 vendor/yiisoft/extensions.php 文件中加入别名。

  1. 'fancyecommerce/fec' =>
  2. array (
  3. 'name' => 'fancyecommerce/fec',
  4. 'version' => '1.1.2.4',
  5. 'alias' =>
  6. array (
  7. '@fec' => $vendorDir . '/fancyecommerce/fec',
  8. ),
  9. ),

 

vendor/composer/autoload_psr4.php 中加入namespace信息:

  1. 'fecadmin\\' => array($vendorDir . '/fancyecommerce/fec_admin'),
  2. 'fec\\' => array($vendorDir . '/fancyecommerce/fec'),

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值