本文介绍的是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();
内容比较多,写得也比较乱,如果上述内容有误欢迎指正。

typecho路由机制详解的更多相关文章

  1. SPA路由机制详解(看不懂不要钱~~)

    前言 总所周知,随着前端应用的业务功能起来越复杂,用户对于使用体验的要求越来越高,单面(SPA)成为前端应用的主流形式.而大型单页应用最显著特点之一就是采用的前端路由跳转子页面系统,通过改变页面的UR ...

  2. WebApi路由机制详解

    随着前后端分离的大热,WebApi在项目中的作用也是越来越重要,由于公司的原因我之前一直没有机会参与前后端分离的项目,但WebApi还是要学的呀,因为这东西确实很有用,可单独部署.与前端和App交互都 ...

  3. 从mixin到new和prototype:Javascript原型机制详解

    从mixin到new和prototype:Javascript原型机制详解   这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...

  4. 浏览器 HTTP 协议缓存机制详解

    最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...

  5. JVM的垃圾回收机制详解和调优

    JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...

  6. ThreadPoolExecutor运转机制详解

    ThreadPoolExecutor运转机制详解 - 走向架构师之路 - 博客频道 - CSDN.NET 最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看 ...

  7. Linux 内存机制详解宝典

    Linux 内存机制详解宝典 在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时(还够用),不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于 ...

  8. PHP的垃圾回收机制详解

    原文:PHP的垃圾回收机制详解 最近由于使用php编写了一个脚本,模拟实现了一个守护进程,因此需要深入理解php中的垃圾回收机制.本文参考了PHP手册. 在理解PHP垃圾回收机制(GC)之前,先了解一 ...

  9. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

随机推荐

  1. 安装wampserver2时出现的问题

    提示丢失MSVCR100.dll 如果安装其他软件也是同样的提示情况,估计也是这个原因,以下分别是32位与64位的VC10下载地址: VC10 SP1 vcredist_x86.exe 32 bits ...

  2. 利用sql命令把结果集输出到文件

    利用sql命令把结果集输出到文件 红色部分的三条命令完成把结果集输出到文件!! [root@test root]# psql -hlocalhost -Utest testWelcome to psq ...

  3. KMP算法总♂结

    讲KM♂P算法之前,我们先讲一个故♂事. 有一天,sgg给了老obo一封信和一个单词,并给他一个任务:找出这封信出现了多少个单词,然后在规定时间内告诉他. 碰到这个问题,老obo会怎么做呢? 首先最直 ...

  4. Subsets II 解答

    Question Given a collection of integers that might contain duplicates, nums, return all possible sub ...

  5. QQ聊天界面的布局和设计(IOS篇)-第一季

    我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...

  6. pyqt最小化学习

    # -*- coding: cp936 -*- #!/usr/bin/env python # -*- coding:utf-8 -*- from PyQt4 import QtCore, QtGui ...

  7. unity3d 建树篇

    今天碰到有人问这个问题,然后我经过一番折腾,找到了方法.例如以下: 有学过Unity3d的同学生都知道我们在对地形拖拉树木等表层时,其树木在我们实例执行中,它们都是能够任其他物体穿过. 这是为什么.相 ...

  8. Afianl加载网络图片(延续)

    上一页"已经谈到了如何使用Afianl网络负载的图片和下载文件,本文将继续介绍使用Afinal使用网络负载图片,主绑定listview采用: 看效果图: listview在滑动过程中没用明显 ...

  9. SQLLoader6(一个或多个数据文件按条件导入不同的表)

    测试一1.创建表: SQL), col2 )); 表已创建. SQL), col2 )); 表已创建. SQL> COMMIT; 提交完成. 2.数据文件:test.txt A A A B B ...

  10. jquery mouseout和mouseleave区别

    mouseout()和mouseleave() 都是鼠标移出元素时触发,但是这两者又有所区别,需要大家留意: 不论鼠标指针离开指定元素还是该元素子元素,都会触发 mouseout 事件. 只有在鼠标指 ...