yii2框架随笔24

今天来看yii.php

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
namespace yii\web;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\caching\Cache;
/**
 * UrlManager handles HTTP request parsing and creation of URLs based on a set of rules.
 * urlmanager处理HTTP请求的解析和基于规则的URL创建。
 *
 * UrlManager is configured as an application component in [[\yii\base\Application]] by default.
 * urlmanager配置为应用程序组件在[ [ \yii\base\Application] ]。
 * You can access that instance via `Yii::$app->urlManager`.
 * 你可以通过`Yii::$app->urlManager`获取内容。
 * You can modify its configuration by adding an array to your application config under `components`
 * as it is shown in the following example:
 * 您可以通过添加一个数组到您的应用程序配置下的组件修改其配置,
 *  正如下面的例子所示:
 * ~~~
 * 'urlManager' => [
 *     'enablePrettyUrl' => true,
 *     'rules' => [
 *         // 你的规则在这设置
 *     ],
 *     // ...
 * ]
 * ~~~
 *
 * @property string $baseUrl The base URL that is used by [[createUrl()]] to prepend to created URLs.
 * 基础URL使用的是[[createurl()]]前置生成的URL
 * @property string $hostInfo The host info (e.g. "http://www.example.com") that is used by
 * [[createAbsoluteUrl()]] to prepend to created URLs.
 * 主机信息(例如“HTTP:/ / www.example .com”)所使用的[[createabsoluteurl()]]前置到生成的URL。
 * @property string $scriptUrl The entry script URL that is used by [[createUrl()]] to prepend to created
 * URLs.
 * The entry脚本的URL.
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class UrlManager extends Component
{
    /**
     * @var boolean whether to enable pretty URLs.
     *
     * 是否开启 pretty URLs
     */
    public $enablePrettyUrl = false;
    /**
     * @var boolean whether to enable strict parsing.
     * 是否启用了严格的解析
     */
    public $enableStrictParsing = false;
    /**
     * @var array the rules for creating and parsing URLs when [[enablePrettyUrl]] is true.
     * 规则创建和解析URL时[[enableprettyurl]]是真的。
     * Note that if you modify this property after the UrlManager object is created, make sure
     * you populate the array with rule objects instead of rule configurations.
     * 注意如果你修改该属性后,urlmanager对象就会创建,确保
     * 您用规则对象填充数组,而不是规则配置。
     * 配置的 rules 存储在这个数组里
     */
    public $rules = [];
    /**
     * @var string the URL suffix used when in 'path' format.
     * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
     * This property is used only if [[enablePrettyUrl]] is true.
     *
     * 后缀名,只有在 $enablePrettyUrl 是 true 时,才起作用。
     * 如果 pretty url 是 /news/Yii-is-released,$suffix 是 '.html'
     * 则最后的 url 会是 /news/Yii-is-released.html
     */
    public $suffix;
    /**
     * @var boolean whether to show entry script name in the constructed URL. Defaults to true.
     * This property is used only if [[enablePrettyUrl]] is true.
     *
     * 是否展示入口脚本 index.php
     */
    public $showScriptName = true;
    /**
     * @var string the GET parameter name for route. This property is used only if [[enablePrettyUrl]] is false.
     *
     * $enablePrettyUrl 是 false 时,默认的 router 的参数名
     */
    public $routeParam = 'r';
    /**
     * @var Cache|string the cache object or the application component ID of the cache object.
     * Compiled URL rules will be cached through this cache object, if it is available.
     *
     * After the UrlManager object is created, if you want to change this property,
     * you should only assign it with a cache object.
     * Set this property to false if you do not want to cache the URL rules.
     *
     * 用来缓存 route 规则的 component 的名称,默认为cache
     * 不想使用缓存存储 route 规则的话,就将它设置为 false
     */
    public $cache = 'cache';
    /**
     * @var array the default configuration of URL rules. Individual rule configurations
     * specified via [[rules]] will take precedence when the same property of the rule is configured.
     * 网址规则的默认配置,通过[ [ [规则] ]指定的个别规则配置将优先于规则的同一属性配置。
     */
    public $ruleConfig = ['class' => 'yii\web\UrlRule'];
    private $_baseUrl;
    private $_scriptUrl;
    private $_hostInfo;
    /**
     * Initializes UrlManager.
     */
    public function init()
    {
        parent::init();
        if (!$this->enablePrettyUrl || empty($this->rules)) {
            return;
        }
        if (is_string($this->cache)) {
            // 如果 $cache 是字符串,就将它初始化为 cache component
            $this->cache = Yii::$app->get($this->cache, false);
        }
        if ($this->cache instanceof Cache) {
            // 如果 $cache 继承了 Cache,就说明有 cache component
            // 使用当前的类名称作为缓存的 key 值
            $cacheKey = __CLASS__;
            // 根据 rules 的内容,使用MD5算出其hash的值,用于判断缓存是否失效
            $hash = md5(json_encode($this->rules));
            if (($data = $this->cache->get($cacheKey)) !== false && isset($data[1]) && $data[1] === $hash) {
                // 能够获取到缓存,而且缓存没有失效,就将缓存中的rules保存到该对象的rules属性中
                $this->rules = $data[0];
            } else {
                // 缓存失效,或着未取到相应的缓存,就重新构建rules,并存到缓存中
                $this->rules = $this->buildRules($this->rules);
                $this->cache->set($cacheKey, [$this->rules, $hash]);
            }
        } else {
            // 没有开启cache,就直接构建rules
            $this->rules = $this->buildRules($this->rules);
        }
    }

    /**
     * Builds URL rule objects from the given rule declarations.
     * 从给定的规则声明中构建链接规则对象。
     * @param array $rules the rule declarations. Each array element represents a single rule declaration.
     * Please refer to [[rules]] for the acceptable rule formats.
     * 每个数组元素代表一个单独的规则声明。请参阅[  [规则] ] ]可接受的规则格式。
     * @return UrlRuleInterface[] the rule objects built from the given rule declarations
     * @throws InvalidConfigException if a rule declaration is invalid
     */
    protected function buildRules($rules)
    {
        $compiledRules = [];
        // 支持的请求方法
        $verbs = 'GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS';
        foreach ($rules as $key => $rule) {
            if (is_string($rule)) {
                $rule = ['route' => $rule];
                if (preg_match("/^((?:($verbs),)*($verbs))\\s+(.*)$/", $key, $matches)) {
                    // 匹配rules中相应的请求方法
                    // 正则表达式的分析如下
                    // http://jex.im/regulex/#!embed=false&flags=&re=%5E((%3F%3A(GET%7CHEAD%7CPOST%7CPUT%7CPATCH%7CDELETE%7COPTIONS)%2C)*(GET%7CHEAD%7CPOST%7CPUT%7CPATCH%7CDELETE%7COPTIONS))%5Cs%2B(.*)%24
                    $rule['verb'] = explode(',', $matches[1]);
                    // rules that do not apply for GET requests should not be use to create urls
                    // 不适用于获取请求的规则不应该用来创建网址
                    if (!in_array('GET', $rule['verb'])) {
                        $rule['mode'] = UrlRule::PARSING_ONLY;
                    }
                    $key = $matches[4];
                }
                $rule['pattern'] = $key;
                // 假设$rule初始为 PUT,POST <controller:\w+>/<id:\d+>
                // 最终$rule的结构如下
                // [
                //   'route'=>'PUT,POST <controller:\w+>/<id:\d+>'
                //   'verb'=>['PUT','POST'],
                //   'pattern'=>’<controller:\w+>/<id:\d+>
                // ]
            }
            if (is_array($rule)) {
                // 默认创建yii\web\UrlRule对象,也可以自定义相应的UrlRule类
                $rule = Yii::createObject(array_merge($this->ruleConfig, $rule));
            }
            if (!$rule instanceof UrlRuleInterface) {
                throw new InvalidConfigException('URL rule class must implement UrlRuleInterface.');
                //抛出一条信息"URL规则的类必须实现urlruleinterface"。
            }
            $compiledRules[] = $rule;
        }
        return $compiledRules;
    }

 

posted @ 2016-05-05 22:38  TTKKK  阅读(432)  评论(0编辑  收藏  举报