首页 > 其他分享 >Url管理-请求与响应-(4.2)深入理解YII2.0

Url管理-请求与响应-(4.2)深入理解YII2.0

时间:2023-02-23 21:07:27浏览次数:48  
标签:缓存 4.2 Url cache YII2.0 URL rules 规则 路由


Url管理

在Web开发中,对于URL有一些共性的需求,如:

  • 统一、简洁的URL创建方式
  • URL的伪静态化(美化)处理
  • 从URL中解析出相应的路由信息,引导应用执行后续处理

这些功能在 前面我们讲的 UrlRule 层面已经得到了一定程度的实现。 但从层次上来讲,UrlRule 更偏向于基础一些,直接使用 UrlRule 相对而言还不是很方便。

比如,针对各种类型的URL,我们需要提供相应的 UrlRule 实例来进行处理。 这些实例如何进行统一管理,相互关系怎么处理?都无法在 UrlRule 自身层面解决。

我们需要更贴近开发的接口。于是Yii把Web应用中对于URL的常用要求抽象到了urlManager中, 并作为Web应用的核心组件,更便于开发者使用。

urlManager概览

urlManager组件由 yii\web\UrlManager 类定义:

class UrlManager extends Component
{

// 用于表明urlManager是否启用URL美化功能,在Yii1.1中称为path格式URL,
// Yii2.0中改称美化。
// 默认不启用。但实际使用中,特别是产品环境,一般都会启用。
public $enablePrettyUrl = false;

// 是否启用严格解析,如启用严格解析,要求当前请求应至少匹配1个路由规则,
// 否则认为是无效路由。
// 这个选项仅在 enablePrettyUrl 启用后才有效。
public $enableStrictParsing = false;

// 保存所有路由规则的配置数组,并不在这里保存路由规则的实例
public $rules = [];

// 指定续接在URL后面的一个后缀,如 .html 之类的。仅在 enablePrettyUrl 启用时有效。
public $suffix;

// 指定是否在URL在保留入口脚本 index.php
public $showScriptName = true;

// 指定不启用 enablePrettyUrl 情况下,URL中用于表示路由的查询参数,默认为 r
public $routeParam = 'r';

// 指定应用的缓存组件ID,编译过的路由规则将通过这个缓存组件进行缓存。
// 由于应用的缓存组件默认为 cache ,所以这里也默认为 cache 。
// 如果不想使用缓存,需显式地置为 false
public $cache = 'cache';

// 路由规则的默认配置,注意上面的 rules[] 中的同名规则,优先于这个默认配置的规则。
public $ruleConfig = ['class' => 'yii\web\UrlRule'];

private $_baseUrl;
private $_scriptUrl;
private $_hostInfo;

// urlManager 初始化
public function init()
{
parent::init();
// 如果未启用 enablePrettyUrl 或者没有指定任何的路由规则,
// 这个urlManager不需要进一步初始化。
if (!$this->enablePrettyUrl || empty($this->rules)) {
return;
}

// 初始化前, $this->cache 是缓存组件的ID,是个字符串,需要获取其实例。
if (is_string($this->cache)) {
// 如果获取不到实例,说明应用不提供缓存功能,
// 那么置这个 $this->cache 为false
$this->cache = Yii::$app->get($this->cache, false);
}

// 如果顺利引用到了缓存组件,那么就将路由规则缓存起来
if ($this->cache instanceof Cache) {

// 以当前urlManager类的类名为缓存的键
$cacheKey = __CLASS__;
// urlManager所有路由规则转换为json格式编码后的HASH值,
// 用于确保缓存中的路由规则没有变化。
// 即外部没有对已经缓存起来的路由规则有增加、修改、
// 删除、调整前后位置等操作。
$hash = md5(json_encode($this->rules));

// cache中是一个数组, 0号元素用于缓存创建好的路由规则,
// 1号元素用于保存HASH值。这个判断用于确认是否有缓存、且缓存仍有效。
// 是的话,直接使用缓存中的内容作为当前的路由规则数组。
if (($data = $this->cache->get($cacheKey)) !== false
&& isset($data[1]) && $data[1] === $hash) {
$this->rules = $data[0];

// 如果尚未缓存或路由规则已经被修改导致缓存失效,
// 那么重新创建路由规则并缓存。
} else {
$this->rules = $this->buildRules($this->rules);
$this->cache->set($cacheKey, [$this->rules, $hash]);
}

// 要么是应用不提供缓存功能,要么是开发者将 $this->cache 手动置为false,
// 总之,就是不使用缓存。那么就直接创建吧,也无需缓存了。
} else {
$this->rules = $this->buildRules($this->rules);
}
}

// 增加新的规则
public function addRules($rules, $append = true){ ... }

// 创建路由规则
protected function buildRules($rules){ ... }

// 用于解析请求
public function parseRequest($request){ ... }

// 这2个用于创建URL
public function createUrl($params){ ... }
public function createAbsoluteUrl($params, $scheme = null){ ... }
}

在urlManager的使用上,用得最多的配置项就是:

  • $enablePrettyUrl ,是否开启URL美化功能。关于美化功能,我们在 路由(Route) 部分已经介绍过了。 注意如果 $enablePrettyUrl 不开启,表明使用原始的格式,那么所有路由规则都是无效的。
  • $showScriptName ,是否在URL中显示入口脚本。是对美化功能的进一步补充。
  • suffix 设置一个 .html 之类的假后缀,是对美化功能的进一步补充。
  • rules 保存路由规则们的声明,注意并非保存其实例。
  • $enableStrictParsing 是否开启严格解析。该选项仅在开启美化功能后生效。在开启严格解析模式时, 所有请求必须匹配 $rules[] 所声明的至少一个路由规则。 如果未开启,请求的PATH_INFO部分将作为所请求的路由进行后续处理。

在 ​​UrlManager::init()​​ 初始化过程中,可以发现 urlManager 使用了应用所提供的缓存组件(有果有的话), 对所有路由规则的实例进行缓存。

从架构上来讲,将所有请求交由入口脚本统一接收,再分发到相应模块进行处理的这种方式, 就注定了入口脚本有产生性能瓶颈的可能。但是带来的开发上的便利,却是实实在在的。 可以想像,在由Web Server进行请求分发的情景下,每个接收请求的脚本都要执行相同或类似的代码, 这会造成很冗余。而且会将权限控制、日志记录等逻辑上就应当作为所有请求第一关的的模块都分散到各处去。

因此,目前这种单一入口脚本的设计成为事实上的标准,几乎所有的Web开发框架都采用这种方式。 但这同时也对各框架的性能提出挑战。

在前面讲路由规则时,我们就体会到了初始化过程的繁琐,转换来转换去的。 如果采用简单粗暴的方式,Yii完全可以牺牲一定的开发便利性,在代码层面提高路由规则的性能。 比如,直接使用正则表达式。

但是,Yii没有这样做,而是很好地平稳了性能与开发便利性,通过将路由规则进行缓存来克服这个瓶颈。

标签:缓存,4.2,Url,cache,YII2.0,URL,rules,规则,路由
From: https://blog.51cto.com/u_15967457/6081730

相关文章

  • 路由(Route)-请求与响应-(4.1)深入理解YII2.0
    路由(Route)Web开发中不可避免的要使用到URL。用得最多的,就是生成一个指向应用中其他某个页面的URL了。开发者需要一个简洁的、集中的、统一的方法来完成这一过程。否则的......
  • 事件-Yii 基础-深入理解YII2.0(1.2)
    事件(Event)使用事件,可以在特定的时点,触发执行预先设定的一段代码,事件既是代码解耦的一种方式,也是设计业务流程的一种模式。现代软件中,事件无处不在,比如,你发了个微博,触发了......
  • 依赖注入-Yii 模式-深入理解YII2.0(3.2)
    依赖注入和依赖注入容器为了降低代码耦合程度,提高项目的可维护性,Yii采用多许多当下最流行又相对成熟的设计模式,包括了依赖注入(​​DenpdencyInjection,DI​​​)和服务定......
  • Yii2.0中的PSR规范
    什么是PSR?PSR是PHPStandardsRecommendation的简称,这个是​​php-fig​​​组织制定的一套​​规范​​。至今,php-fig已经发布了五个规范:PSR-0:自动加载标准,2014-10-21该标......
  • 使用 curl 命令分析请求的耗时情况
    最近工作中遇到一个问题,某个请求的响应特别慢,因此我就希望有一种方法能够分析到底请求的哪一步耗时比较长,好进一步找到问题的原因。在网络上搜索了一下,发现了一个非常好用......
  • URLDNS链子
    URLDNS链子我们想要反序列化HashMap类,势必会去调用readObject()方法。而如何利用HashMap中的重写不当的readObejct()方法就成了关键,我们来看readObject()方法中做了这样......
  • Gunicorn + Flask Curl命令返回状态Connection: close转keep-alive的方法
    问题介绍:在实际的业务中,会存在CURL命令请求后返回值的header中的"Connection:close"的情况,这种情况下会导致每次请求都要重新建立连接。HTTP协议采用“请求-应答”模式......
  • 在地址栏输入 URL 敲下回车后发生了什么?
    一、简单分析简单的分析,从输入 URL到回车后发生的行为如下:URL解析DNS查询TCP连接HTTP请求响应请求页面渲染二、详细分析URL解析首先判断你输入的是一个合......
  • PHP 进行支付宝开发中return_url和notify_url的区别分析
    在支付宝处理业务中return_url,notify_url是返回些什么状态呢,我们要根据它来做一些处理就必须了解return_url,notify_url的区别,下面我就来给大家介绍;一、问题描述:我在......
  • centos宿主机无法ping通docker容器以及dockers容器curl: (56) Recv failure: Connecti
    今天在测试docker容器时,本来配置的一切都挺顺利,放出我的测试经过:dockerrun-d--namenginx-p8080:80nginx然后这个nginx就在后台启动了,我接着使用命令curl127.......