yii2框架深入理解

目录:

1. 理解PSR4 规范

2. 理解composer autoload 的实现

3. 理解yii2 autoload的实现

4. yii2 autoload 与 composer autoload 的联系与区别

5. yii2 核心类的 加载 流程, classmap 作用及意义

6. yii2 container 类/对象 的作用,如何自定义自己的container类

7. yii2 路由规则类,路由管理类 特点,如何自定义自己的路由规则类。

8. 框架常用的函数,但平时写业务不常用的函数

9. Application 类

10. 异常处理的注册,及异常处理

11. 日志处理

1.PSR4 规范、2. composer autoload 的实现

参考博客:

3. yii2 autoload 的实现

vendor/yiisoft/yii2/classes.php  里边定义了 classMap

classMap 是 yii2 核心包 里边 的类的map;  像独立的yii2 包的类不在此数组内:如 yii\gii  ; yii\debug

vendor/yiisoft/yii2/Yii.php

spl_autoload_register(['Yii', 'autoload'], true, true);

注意 第三个参数 true 表示优先 从 yii2  的 autoload 函数 去加载类,再尝试 用 composer 的autoload 函数去 加载类。

    /**
     * Class autoload loader.
     *
     * This method is invoked automatically when PHP sees an unknown class.
     * The method will attempt to include the class file according to the following procedure:
     *
     * 1. Search in [[classMap]];
     * 2. If the class is namespaced (e.g. `yii\base\Component`), it will attempt
     *    to include the file associated with the corresponding path alias
     *    (e.g. `@yii/base/Component.php`);
     *
     * This autoloader allows loading classes that follow the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/)
     * and have its top-level namespace or sub-namespaces defined as path aliases.
     *
     * Example: When aliases `@yii` and `@yii/bootstrap` are defined, classes in the `yii\bootstrap` namespace
     * will be loaded using the `@yii/bootstrap` alias which points to the directory where bootstrap extension
     * files are installed and all classes from other `yii` namespaces will be loaded from the yii framework directory.
     *
     * Also the [guide section on autoloading](guide:concept-autoloading).
     *
     * @param string $className the fully qualified class name without a leading backslash "\"
     * @throws UnknownClassException if the class does not exist in the class file
     */
    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?");
        }
    }

说明: 先从 classMap 中找,没有再看 @+className 的前缀 是否在 self::$aliases 数组中。

self:;$aliases 别名的路径设置 过程如下:

设置 @app 对应的路径

yii\web\Application->setBasePath()

其中: Yii::setAlias('@app', $this->getBasePath());

 

设置@vendor  @bower  @npm 对应的路径

yii\web\Application->preInit()

 

设置@runtime 对应的路径

yii\web\Application->preInit()

 

yii\web\Application->init()

的 bootstrap 中 设置 别名 @webroot  @web 的路径值

parent::bootstrap  从 @vendor/yiisoft/extensions.php

来设置 另外的 extension 的 alias 的 路径值

有:@yii/bootstrap

@yii/swifmailer

@yii/faker

@yii/redis

@yii/elasticsearch

@yii\debug

@yii/gii

@yii/queue

    @yii/queue

    @yii/queue/amqp

    @yii/queue/amqp_interop

    @yii/queue/beanstalk

    @yii/queue/db

    @yii/queue/file

    //….

@yii/mongodb

 

4. yii2 autoload 与 composer autoload 的联系与区别

顺序:

     composer 的autoload 先进行   spl_autoload_register 注册

    再进行 yii2 autoload 的 spl_autoload_register 注册

     找类时 先使用 yii2 autoload 函数 找,再使用 composer 的autoload 函数找

相同点: 都使用 include $file

 

5. yii2 的 classmap 的作用

    快速找到yii2 core 类的 路径 ,可加快core 类 include 速度

    可以 改变/classmap 数组的元素  value ; 也可以添加 一个 元素 如:

  添加一个元素如:

spl_autoload_register(['Yii', 'autoload'], true, true);
Yii::$classMap = require __DIR__ . '/../vendor/yiisoft/yii2/classes.php';
Yii::$classMap['app\components\Container'] = __DIR__. '/../components/Container.php';
Yii::$container = new app\components\Container();

 也可以改变 一个元素的 value :

spl_autoload_register(['Yii', 'autoload'], true, true);
Yii::$classMap = require __DIR__ . '/../vendor/yiisoft/yii2/classes.php';
Yii::$classMap['yii\di\Container'] = __DIR__. '/../components/Container.php';
Yii::$container = new yii\di\Container();

  这种方式 可以达到的目的是: 完全替换 yii2  核心类 ,以满足自己改造的需求,

   注意Container.php 中 namespace  和 核心类 要完全一样

   通过这种方式 classes.php 中的 core 类 可以被完全替换。

 

6. yii2 container 类/对象 的作用

     作用: 1. 创建yii2 的其它类的对象, 2 创建用户的类的对象,并解决了依赖对象

     原理 它 很早被实例化,其属性 被 Application  用 config 下相应的配置来 赋值

    对它的改造: 1 是完全替换, 2是 自定义Container 类 来继承 yii2 核心的 container 类

container 的配置

config/container.php

    'redisLua' => 'app\tool\RedisLua',
    
    'redisLua' => app\tool\RedisLua::class,

    'redisLua' => [
        'app\tool\RedisLua',
        []                      //对应container->get(...) 中 params参数,是依赖
    ],
    
    'redisLua' => [             //注意这样写报错!!! yii\base\InvalidConfigException
        ['app\tool\RedisLua'],  //因为,这个元素要被解析为 define ,要么如上个写法是字符串,要么是数组当必须有 class=> '...',如下例子
        []
    ],
    

    'redisLua' => [
        [
            'class' => 'app\tool\RedisLua',
            'apcu' => true,
        ],
        []
    ],
    
    'redisLua' => [
        'class' => app\tool\RedisLua::class,
        'apcu' => $params['enableLuaApcu'],
    ],
    
];

$definitions = [];
return [
    'definitions' => $definitions, //在容器中注册类定义
    'singletons' => $singletons,  //使用容器注册类定义并将该类标记为单例类
];

 

 

7. yii2 路由规则类、路由管理类urlManager

     

      'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                //优先验证是否符合自定义的规则
                [
                    'class' => 'app\components\ApiRule',
                    'apcu' => false, //是否使用apcu 缓存,false 默认不使用; 注意若使用,必须安装apcu扩展
                ],
                '/e/<controller:[\w\-]+>/<action:[\w\-]+>' => '/encryt/<controller>/<action>', //需要授权验证的Url规则美化重写
                '<controller:[\w\-]+>/<action:[\w\-]+>' => '<controller>/<action>', //普通美化

            ],
        ],

urlManger 特点: 从rules 中 依次 获取 规则 如果匹配到则 不执行余下的规则匹配。

                  每条规则 如果没有class 这样的key 则使用 yii\web\UrlRule 来实例化一个rule类。

自定义的rule 类要实现 UrlRuleInterface 接口

 

8. 框架常用的函数,但平时写业务不常用的函数

类型判断类:   is_callable、  is_object 

call_user_func
call_user_func_array

反射:

\ReflectionMethod
\ReflectionFunction

9. yii\web\Application

   

10. 异常处理的注册,及异常处理

异常的注册

在Application 对象实例化的 构造函数中:

执行 $this->registerErrorHandler($config);

创建  yii\web\ErrorHandler 对象

执行对象的 register() 方法

register() 方法定义在父类 ( yii\base\ErrorHandler)中

函数 register() 来注册异常的处理:

主要内容是:

set_exception_handler 注册handleException函数   

set_error_handler  注册handleError 函数

register_shutdown_function() 注册handleFatalError函数 

 

 

异常的执行

404异常:

执行由 set_exception_handler 注册 的 renderException函数,

这个函数 是 yii\web\ErrorHandler的 方法

 

执行 $this->renderException($exception);

执行exit(1);

执行 yii\bas\ErrorHandler 的 handleFatalError方法

 

11.  日志处理

对象/类 

yii\log\Logger  日志管理者 

yii\logTarget  日志目标 负责将 日志  导出到 媒介中。

Logger 对象 

属性有:

       $message = []

       使用 log 方法记录信息 (yii::info yii::error 内部就是 log方法)

属性有:

       $flushInterval = 1000;

       用途 在 log 方法中如果 $message的数量 >= $flushInterval 就 执行 flush()

logger 的 flush() 方法内容就是:

      把消息分发给 targets 

      把自己的messages 置空

target 的 消息 是什么时候export

它的messages 数量 >= exportInterval 时

 

时候时候还会 export() ?

在执行 handleFatalError() 

exit前最后一步会执行: Yii::getLogger()->flush(true);

handleException() 中 非YII_ENV_TEST 时  exit前 会执行: \Yii::getLogger()->flush(true);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值