• yii2框架随笔29


    今天我们来看UrlRule.php

    <?php
    /**
     * @link http://www.yiiframework.com/
     * @copyright Copyright (c) 2008 Yii Software LLC
     * @license http://www.yiiframework.com/license/
     */
    namespace yiiweb;
    use Yii;
    use yiibaseObject;
    use yiibaseInvalidConfigException;
    /**
     * UrlRule represents a rule used by [[UrlManager]] for parsing and generating URLs.
     * urlrule代表由[[urlmanager]]用于解析和生成的URL规则
     * To define your own URL parsing and creation logic you can extend from this class
     * and add it to [[UrlManager::rules]] like this:
     * 定义自己的网址解析和创建逻辑,您可以从这个类扩展添加到[规则] ] [ urlmanager::像这样:
     * ~~~
     * 'rules' => [
     *     ['class' => 'MyUrlRule', 'pattern' => '...', 'route' => 'site/index', ...],
     *     // ...
     * ]
     * ~~~
     *
     * rule中class的默认值是yiiwebUrlRule
     *
     * @author Qiang Xue <qiang.xue@gmail.com>
     * @since 2.0
     */
    class UrlRule extends Object implements UrlRuleInterface
    {
        /**
         * Set [[mode]] with this value to mark that this rule is for URL parsing only
         * 集[ [model] ]与这个值,以标记这条规则是唯一的网址解析
         */
        const PARSING_ONLY = 1;
        /**
         * Set [[mode]] with this value to mark that this rule is for URL creation only
         * 集[ [model] ]与这个值,以标记这条规则是唯一的网址解析
         */
        const CREATION_ONLY = 2;
        /**
         * @var string the name of this rule. If not set, it will use [[pattern]] as the name.
         * 这个规则的名称。如果没有设置,它将使用[ [模式] ]作为名称。
         */
        public $name;
        /**
         * @var string the pattern used to parse and create the path info part of a URL.
         * 用来解析和创建一个链接的路径信息的模式。
         * @see host
         */
        public $pattern;
        /**
         * @var string the pattern used to parse and create the host info part of a URL (e.g. `http://example.com`).
         * @see pattern
         * 用于解析和创建一个URL的主机信息的模式(例如`http://example.com`)。
         */
        public $host;
        /**
         * @var string the route to the controller action
         * 控制器作用的路径
         */
        public $route;
        /**
         * @var array the default GET parameters (name => value) that this rule provides.
         * 该规则提供的默认参数(名称=值)。
         * When this rule is used to parse the incoming request, the values declared in this property
         * will be injected into $_GET.
         * 当这个规则被用来解析传入的请求时,在这个属性中声明的值将注入$_GET。
         */
        public $defaults = [];
        /**
         * @var string the URL suffix used for this rule.
         * 用于此规则的网址后缀。
         * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
         * 例如,“HTML”可以使URL看起来像指向一个静态HTML页面。
         * If not, the value of [[UrlManager::suffix]] will be used.
         * 例如,“HTML”可以使URL看起来像指向一个静态HTML页面。
         */
        public $verb;
        /**
         * @var integer a value indicating if this rule should be used for both request parsing and URL creation,parsing only, or creation only.
         * 一个值,该值表示,如果该规则应用于请求分析和链接创建,只分析或创建。
         *
         * If not set or 0, it means the rule is both request parsing and URL creation.
         * 如果没有设置或0,这意味着规则是请求解析和链接创建。
         * If it is [[PARSING_ONLY]], the rule is for request parsing only.
         * 如果是[[parsing_only]],规则是只要求解析。
         * If it is [[CREATION_ONLY]], the rule is for URL creation only.
         * 如果是[[creation_only]],规则是URL只有创造。
         */
        public $mode;
        /**
         * @var boolean a value indicating if parameters should be url encoded.
         * 返回一个boolean值,该值指示如果参数应该是网址编码。
         */
        public $encodeParams = true;
        /**
         * @var string the template for generating a new URL. This is derived from [[pattern]] and is used in generating URL.
         * 生成一个新的网址的模板。这是源于[[pattern]] ,并用于产生网址。
         */
        private $_template;
        /**
         * @var string the regex for matching the route part. This is used in generating URL.
         * 该路线的部分匹配正则表达式。这是用来产生网址。
         */
        private $_routeRule;
        /**
         * @var array list of regex for matching parameters. This is used in generating URL.
         * list of regex for matching parameters. This is used in generating URL.
         */
        private $_paramRules = [];
        /**
         * @var array list of parameters used in the route.
         * 路由的参数存储数组
         */
        private $_routeParams = [];
        /**
         * Initializes this rule.
         */
        public function init()
        {
            if ($this->pattern === null) {
                throw new InvalidConfigException('UrlRule::pattern must be set.');
            }
            if ($this->route === null) {
                throw new InvalidConfigException('UrlRule::route must be set.');
            }
            if ($this->verb !== null) {
                // 将verb变成数组,并将器内容全部大写
                if (is_array($this->verb)) {
                    foreach ($this->verb as $i => $verb) {
                        $this->verb[$i] = strtoupper($verb);
                    }
                } else {
                    $this->verb = [strtoupper($this->verb)];
                }
            }
            if ($this->name === null) {
                $this->name = $this->pattern;
            }
            $this->pattern = trim($this->pattern, '/');
            $this->route = trim($this->route, '/');
            if ($this->host !== null) {
                // host存在
                $this->host = rtrim($this->host, '/');
                $this->pattern = rtrim($this->host . '/' . $this->pattern, '/');
            } elseif ($this->pattern === '') {
                // pattern为空
                $this->_template = '';
                $this->pattern = '#^$#u';
                return;
            } elseif (($pos = strpos($this->pattern, '://')) !== false) {
                // 存在'://'字符串
                if (($pos2 = strpos($this->pattern, '/', $pos + 3)) !== false) {
                    // 找到'://'之后的第一个'/'的位置,并截取之前的字符串作为host
                    $this->host = substr($this->pattern, 0, $pos2);
                } else {
                    $this->host = $this->pattern;
                }
            } else {
                $this->pattern = '/' . $this->pattern . '/';
            }
            /**
             * $rule的结构如下
             * [
             *     'route'=>'PUT,POST <controller:w+>/<id>'
             *     'verb'=>['PUT','POST'],
             *     'pattern'=>'<controller:w+>/<id>'
             * ]
             */
            if (strpos($this->route, '<') !== false && preg_match_all('/<(w+)>/', $this->route, $matches)) {
                // 匹配不带正则表达式的路由配置,并放入_routeParams中存起来
                // 如上的例子中,$matches[1]=['id']
                foreach ($matches[1] as $name) {
                    $this->_routeParams[$name] = "<$name>";
                }
            }
            $tr = [
                '.' => '\.',
                '*' => '\*',
                '$' => '\$',
                '[' => '\[',
                ']' => '\]',
                '(' => '\(',
                ')' => '\)',
            ];
            $tr2 = [];
            /**
             * 匹配带正则表达式的路由配置
             * PREG_PATTERN_ORDER
             *   结果排序为$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配,以此类推。
             *
             * PREG_SET_ORDER
             *   结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组,以此类推。
             *
             * PREG_OFFSET_CAPTURE
             *   如果这个标记被传递,每个发现的匹配返回时会增加它相对目标字符串的偏移量。
             *   注意这会改变matches中的每一个匹配结果字符串元素,使其成为一个第0个元素为匹配结果字符串,第1个元素为 匹配结果字符串在subject中的偏移量。
             *
             * 如果没有给定排序标记,假定设置为PREG_PATTERN_ORDER。
             *
             * 如果$this->pattern是'<controller:w+>/<id:d+>'
             * 则$matches为[
             *     [['<controller:w+>', 0], ['controller', 1], ['w+', 12]],
             *     [['<id:d+>', 17], ['id', 18], ['d+', 21]]
             * ]
             */
            if (preg_match_all('/<(w+):?([^>]+)?>/', $this->pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
                foreach ($matches as $match) {
                    // 以第一条记录为例
                    // $name = 'controller'
                    $name = $match[1][0];
                    // $pattern = 'w+'
                    // 如果正则表达式的匹配值为空,则默认为'[^/]+'
                    $pattern = isset($match[2][0]) ? $match[2][0] : '[^/]+';
                    if (array_key_exists($name, $this->defaults)) {
                        $length = strlen($match[0][0]);
                        $offset = $match[0][1];
                        if ($offset > 1 && $this->pattern[$offset - 1] === '/' && $this->pattern[$offset + $length] === '/') {
                            $tr["/<$name>"] = "(/(?P<$name>$pattern))?";
                        } else {
                            $tr["<$name>"] = "(?P<$name>$pattern)?";
                        }
                    } else {
                        // str['<controller>'] = '(?P<controller>w+)'
                        $tr["<$name>"] = "(?P<$name>$pattern)";
                    }
                    if (isset($this->_routeParams[$name])) {
                        $tr2["<$name>"] = "(?P<$name>$pattern)";
                    } else {
                        $this->_paramRules[$name] = $pattern === '[^/]+' ? '' : "#^$pattern$#u";
                    }
                }
            }
            // 如果$this->pattern是'<controller:w+>/<id:d+>'
            // 则$this->_template是'<controller>/<id>'
            $this->_template = preg_replace('/<(w+):?([^>]+)?>/', '<$1>', $this->pattern);
            // $this->pattern最终是'#^(?P<controller>w+)/(?P<id>d+)$#u'
            $this->pattern = '#^' . trim(strtr($this->_template, $tr), '/') . '$#u';
            if (!empty($this->_routeParams)) {
                $this->_routeRule = '#^' . strtr($this->route, $tr2) . '$#u';
            }
        }
  • 相关阅读:
    sql server 中隐藏掉无关数据库
    Web Deploy自动配置
    jQuery form表单序列化为JSON对象!
    CURL HELP
    sql server生成递归日期、连续数据
    MVC项目中,如何访问Views目录下的静态文件!
    DDNS动态更新
    佛祖保佑 永无bug
    asp.net webservice返回json问题
    asp.net使用Get请求webservice
  • 原文地址:https://www.cnblogs.com/taokai/p/5480005.html
Copyright © 2020-2023  润新知