typecho路由机制详解

本文介绍的是typecho的路由机制,引自 不烦恼
路由机制是typecho的核心,有很多功能都是基于路由功能设计的,理解并熟悉TE的路由机制将非常有助于插件的开发。

完整的路由表如下:

array (
0 =>
array (
'index' =>
array (
'url' => '/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^[/]?$|',
'format' => '/',
'params' =>
array (
),
),
'do' =>
array (
'url' => '/action/[action:alpha]',
'widget' => 'Widget_Do',
'action' => 'action',
'regx' => '|^/action/([_0-9a-zA-Z-]+)[/]?$|',
'format' => '/action/%s',
'params' =>
array (
0 => 'action',
),
),
'post' =>
array (
'url' => '/archives/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/archives/([0-9]+)[/]?$|',
'format' => '/archives/%s/',
'params' =>
array (
0 => 'cid',
),
),
'attachment' =>
array (
'url' => '/attachment/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/attachment/([0-9]+)[/]?$|',
'format' => '/attachment/%s/',
'params' =>
array (
0 => 'cid',
),
),
'category' =>
array (
'url' => '/category/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/category/([^/]+)[/]?$|',
'format' => '/category/%s/',
'params' =>
array (
0 => 'slug',
),
),
'tag' =>
array (
'url' => '/tag/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/tag/([^/]+)[/]?$|',
'format' => '/tag/%s/',
'params' =>
array (
0 => 'slug',
),
),
'author' =>
array (
'url' => '/author/[uid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/author/([0-9]+)[/]?$|',
'format' => '/author/%s/',
'params' =>
array (
0 => 'uid',
),
),
'search' =>
array (
'url' => '/search/[keywords]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/search/([^/]+)[/]?$|',
'format' => '/search/%s/',
'params' =>
array (
0 => 'keywords',
),
),
'index_page' =>
array (
'url' => '/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/page/([0-9]+)[/]?$|',
'format' => '/page/%s/',
'params' =>
array (
0 => 'page',
),
),
'category_page' =>
array (
'url' => '/category/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/category/([^/]+)/([0-9]+)[/]?$|',
'format' => '/category/%s/%s/',
'params' =>
array (
0 => 'slug',
1 => 'page',
),
),
'tag_page' =>
array (
'url' => '/tag/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/tag/([^/]+)/([0-9]+)[/]?$|',
'format' => '/tag/%s/%s/',
'params' =>
array (
0 => 'slug',
1 => 'page',
),
),
'author_page' =>
array (
'url' => '/author/[uid:digital]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/author/([0-9]+)/([0-9]+)[/]?$|',
'format' => '/author/%s/%s/',
'params' =>
array (
0 => 'uid',
1 => 'page',
),
),
'search_page' =>
array (
'url' => '/search/[keywords]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/search/([^/]+)/([0-9]+)[/]?$|',
'format' => '/search/%s/%s/',
'params' =>
array (
0 => 'keywords',
1 => 'page',
),
),
'archive_year' =>
array (
'url' => '/[year:digital:4]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})[/]?$|',
'format' => '/%s/',
'params' =>
array (
0 => 'year',
),
),
'archive_month' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})[/]?$|',
'format' => '/%s/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
),
),
'archive_day' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/([0-9]{2})[/]?$|',
'format' => '/%s/%s/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'day',
),
),
'archive_year_page' =>
array (
'url' => '/[year:digital:4]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/page/([0-9]+)[/]?$|',
'format' => '/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'page',
),
),
'archive_month_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/page/([0-9]+)[/]?$|',
'format' => '/%s/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'page',
),
),
'archive_day_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([0-9]{4})/([0-9]{2})/([0-9]{2})/page/([0-9]+)[/]?$|',
'format' => '/%s/%s/%s/page/%s/',
'params' =>
array (
0 => 'year',
1 => 'month',
2 => 'day',
3 => 'page',
),
),
'comment_page' =>
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' =>
array (
0 => 'permalink',
1 => 'commentPage',
),
),
'feed' =>
array (
'url' => '/feed[feed:string:0]',
'widget' => 'Widget_Archive',
'action' => 'feed',
'regx' => '|^/feed(.*)[/]?$|',
'format' => '/feed%s',
'params' =>
array (
0 => 'feed',
),
),
'feedback' =>
array (
'url' => '[permalink:string]/[type:alpha]',
'widget' => 'Widget_Feedback',
'action' => 'action',
'regx' => '|^(.+)/([_0-9a-zA-Z-]+)[/]?$|',
'format' => '%s/%s',
'params' =>
array (
0 => 'permalink',
1 => 'type',
),
),
'page' =>
array (
'url' => '/[slug].html',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^/([^/]+)\\.html[/]?$|',
'format' => '/%s.html',
'params' =>
array (
0 => 'slug',
),
),
),
'index' =>
array (
'url' => '/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'do' =>
array (
'url' => '/action/[action:alpha]',
'widget' => 'Widget_Do',
'action' => 'action',
),
'post' =>
array (
'url' => '/archives/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'attachment' =>
array (
'url' => '/attachment/[cid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'category' =>
array (
'url' => '/category/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'tag' =>
array (
'url' => '/tag/[slug]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'author' =>
array (
'url' => '/author/[uid:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'search' =>
array (
'url' => '/search/[keywords]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'index_page' =>
array (
'url' => '/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'category_page' =>
array (
'url' => '/category/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'tag_page' =>
array (
'url' => '/tag/[slug]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'author_page' =>
array (
'url' => '/author/[uid:digital]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'search_page' =>
array (
'url' => '/search/[keywords]/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_year' =>
array (
'url' => '/[year:digital:4]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_month' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_day' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_year_page' =>
array (
'url' => '/[year:digital:4]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_month_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'archive_day_page' =>
array (
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'comment_page' =>
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
),
'feed' =>
array (
'url' => '/feed[feed:string:0]',
'widget' => 'Widget_Archive',
'action' => 'feed',
),
'feedback' =>
array (
'url' => '[permalink:string]/[type:alpha]',
'widget' => 'Widget_Feedback',
'action' => 'action',
),
'page' =>
array (
'url' => '/[slug].html',
'widget' => 'Widget_Archive',
'action' => 'render',
),
)
上面的数组分为两个部分:
$routingTable[0] 的作用是路由解析(反解析),以下称“路由解析数组”(一个数组$routingTable[0])
$routingTable['string'] 的作用是生成路由解析数组(当$routingTable[0] 不存在时生成routingTable[0]),以下称“路由生成数组”(多个数组$routingTable['string'],string 代表路由名称)
例:
先看路由表中评论页的路由生成数组:

$routingTable = array(
'comment_page' =
array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
)
);
数组中的内容代表什么:
$routingTable 中的 KEY 值 comment_page 是路由名称
$routingTable['comment_page'] 是一个数组,数组中 'url'、'widget'、 'action' 值的作用只是为了生成路由解析数组(见下面的代码,至于如何解析的,可以看 Typecho\Router\Parser.php 中的代码)

再看路由表中评论页的路由解析(反解析)数组(这个是重点,上面的了解就行):

$routingTable = array(
[0] = array(
'comment_page' => array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' => array (
0 => 'permalink',
1 => 'commentPage',
),
),
),
);
数组中的内容代表什么:
$routingTable['0'] 中的 KEY 值 comment_page 是路由名称(可以在路由解析完成后用 Typecho_Router::$current 调用)
$routingTable['0']['comment_page'] 是一个数组,数组中键 'url' 的值是从路由生成数组过渡过来的,其作用是为了生成路由解析数组中的其他三个值,分别为:
一是生成键 'regx'(值的作用是解析 pathInfo 时的正则表达式规则);
二是生成键 'format'(值的作用是反解析路由时生成 pathInfo 的格式);
三是生成键 'params'(值的作用是pathInfo被路由解析后传递给widget的参数),键 'params' 的值是一个数组,数组内容与 'regx' 正则表达式中的子模式顺序值相对应;
键 'widget' 的值是路由解析后分发执行的组件(传递给“组件工厂”);键 'action' 的值是组件实例化后执行的方法。
组件工厂执行流程:

组件实例化(生成组件对象) —— 执行构造函数(将上述 'params' 传递给对象) —— 执行execute方法 —— 执行action方法
完整的例子(扩展讲解):

浏览器中文章评论页的URL:

http://www.bufannao.com/archives/__slide__top__gridLayout.html/comment-page-1
得到文章评论页的 pathInfo 为:

/archives/__slide__top__gridLayout.html/comment-page-1
搜索路由表得到文章评论页的路由为:

$routingTable = array(
[0] = array(
'comment_page' => array (
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => 'Widget_Archive',
'action' => 'render',
'regx' => '|^(.+)/comment-page-([0-9]+)[/]?$|',
'format' => '%s/comment-page-%s',
'params' => array (
0 => 'permalink',
1 => 'commentPage',
),
),
),
);
执行顺序:

Typecho_Widget::widget('Widget_Archive', NULL, array('permalink' => '/archives/__slide__top__gridLayout.html', 'commentPage' => 1));

// $responseObject = Typecho_Response::getInstance();

// $requestObject = new Typecho_Request();
// $requestObject->setParams(array('permalink' => '/archives/__slide__top__gridLayout.html', 'commentPage' => 1));

// 此时$requestObject附加两个属性
// $requestObject->permalink = '/archives/__slide__top__gridLayout.html';
// $requestObject->commentPage = 1;

// $widget = new Widget_Archive($requestObject, $responseObject , null);

// $widget->__construct();

// $widget->execute();

// $widget->render();
内容比较多,写得也比较乱,如果上述内容有误欢迎指正。

转载于:https://www.cnblogs.com/shishd/p/3535713.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值