各位小伙伴,再本套课程中5-24节singwa老师预留了一个作业,需要大家自行的去完成资源路由的解读,现将答案公布如下:
我们已路由设置场景如下:Route::resource('res', 'index/res');
Route::rule('abcd/:name', 'index/hello');
我们都知道在RuleGroup类中的check方法中$rules变量其实有几种对象,第一种就是RuleItem对象:
think\route\RuleItem,另外一种是 : think\route\Resource对象 , $rules变量中的内容再路由设置分析课程内容做了详细的介绍,这里就不过多的讲解了,我们定位到RuleGroup类中的check方法中的foreach 如下代码:// 检查分组路由
foreach ($rules as $key => $item) {
$result = $item->check($request, $url, $completeMatch); // 标注1
if (false !== $result) {
return $result;
}
}
如上代码 标注1中 针对我们的路由配置会有两种场景的走向,第一种就是会请求RuleItem类中的check方法 这个在视频中做了非常详细的讲解,那么第二种就是会请求Resource对象中的check, Resource这个类中并没有check方法,但是他继承了RuleGroup类,这个类中存在check方法,很巧的就是这个方法就是上面标黑的check方法。
图一
然后很多小伙伴就很诡异怎么请求半天又回来了,哈哈,别着急,再编码过程中这种现成很正常,继续看代码如下:
图二
这个时候 我们的当前对象就是 资源Resource对象了, 而上图二中 instanceof关键词是类型运算符 用于确定一个 PHP 变量是否属于某一类 class 的实例 , 他会走到下面这个逻辑,然后请求buildResourceRule方法,这个方法实际是在ResourceRule类中,如下:/**
* 生成资源路由规则
* @access protected
* @return void
*/
protected function buildResourceRule()
{
$origin = $this->router->getGroup(); // think\route\Domain
$this->router->setGroup($this);
$rule = $this->resource;
$option = $this->option;
if (strpos($rule, '.')) {
// 注册嵌套资源路由
$array = explode('.', $rule);
$last = array_pop($array);
$item = [];
foreach ($array as $val) {
$item[] = $val . '/';
}
$rule = implode('/', $item) . '/' . $last;
}
$prefix = substr($rule, strlen($this->name) + 1);
// 注册资源路由
foreach ($this->rest as $key => $val) {
if ((isset($option['only']) && !in_array($key, $option['only']))
|| (isset($option['except']) && in_array($key, $option['except']))) {
continue;
}
if (isset($last) && strpos($val[1], '') && isset($option['var'][$last])) {
$val[1] = str_replace('', '', $val[1]);
} elseif (strpos($val[1], '') && isset($option['var'][$rule])) {
$val[1] = str_replace('', '', $val[1]);
}
$this->addRule(trim($prefix . $val[1], '/'), $this->route . '/' . $val[2], $val[0]);
}
$this->router->setGroup($origin);
}
这个方法主要是对资源路由的多个场景内容做了些处理,下面图三中的内容很关键:
图三
这个地方遍历 让7种资源路由重新 注册到规则中 ($this->addRule()) ,然后请求RuleGroup中的addRule方法,如图四:
图四
这个方法我们在之前路由注册的时候做了详细的分析的,这里老师就不过讲解了, 那么通过这些操作后,我们在回到图一中的check方法,这个时候他的$rules变量就彻底变了 大家可以打印出来看看效果如下:array(4) {
[0] => object(think\route\RuleItem)#22 (10) {
["hasSetRule"] => bool(true)
["name"] => string(15) "index/res/index"
["rule"] => string(3) "res"
["method"] => string(3) "get"
["vars"] => array(0) {
}
["option"] => array(1) {
["complete_match"] => bool(true)
}
["pattern"] => array(0) {
}
["mergeOptions"] => array(6) {
[0] => string(5) "after"
[1] => string(5) "model"
[2] => string(6) "header"
[3] => string(8) "response"
[4] => string(6) "append"
[5] => string(10) "middleware"
}
["doAfter"] => NULL
["lockOption"] => bool(false)
}
[1] => object(think\route\RuleItem)#16 (10) {
["hasSetRule"] => bool(true)
["name"] => string(16) "index/res/create"
["rule"] => string(10) "res/create"
["method"] => string(3) "get"
["vars"] => array(0) {
}
["option"] => array(0) {
}
["pattern"] => array(0) {
}
["mergeOptions"] => array(6) {
[0] => string(5) "after"
[1] => string(5) "model"
[2] => string(6) "header"
[3] => string(8) "response"
[4] => string(6) "append"
[5] => string(10) "middleware"
}
["doAfter"] => NULL
["lockOption"] => bool(false)
}
[2] => object(think\route\RuleItem)#24 (10) {
["hasSetRule"] => bool(true)
["name"] => string(14) "index/res/edit"
["rule"] => string(13) "res//edit"
["method"] => string(3) "get"
["vars"] => array(0) {
}
["option"] => array(0) {
}
["pattern"] => array(0) {
}
["mergeOptions"] => array(6) {
[0] => string(5) "after"
[1] => string(5) "model"
[2] => string(6) "header"
[3] => string(8) "response"
[4] => string(6) "append"
[5] => string(10) "middleware"
}
["doAfter"] => NULL
["lockOption"] => bool(false)
}
[3] => object(think\route\RuleItem)#23 (10) {
["hasSetRule"] => bool(true)
["name"] => string(14) "index/res/read"
["rule"] => string(8) "res/"
["method"] => string(3) "get"
["vars"] => array(0) {
}
["option"] => array(0) {
}
["pattern"] => array(0) {
}
["mergeOptions"] => array(6) {
[0] => string(5) "after"
[1] => string(5) "model"
[2] => string(6) "header"
[3] => string(8) "response"
[4] => string(6) "append"
[5] => string(10) "middleware"
}
["doAfter"] => NULL
["lockOption"] => bool(false)
}
}
细心的同学会发现 这个时候数组里面的内容全是think\route\RuleItem
对象了, 那么这里为什么是 4个 而不是7个呢? 留给大家思考下。然后继续走
图五
通过forach循环 然后调用check方法,那么这个时候就最终走到RuleItem类中的check方法,哈哈又回到了原点,这个RuleItem类中的check方法之前视频中做了详细的分析。 完美了。哈哈。