1.7 新版路由
1.7 版本新增加了路由系统,一般来说,我们只要向系统注入一条路由规则,再实现该条路由 call 的函数,匹配成功后向该函数传入一个数组参数,就实现路由功能了。
增加路由条目的关键是在配置路由规则的数组,如果对路由系统不熟悉,请在应用中心下载 Z-Blog PHP Development Kit 插件,仔细研究系统自带的路由规则。
例子 1(搜索功能伪静态化)
假定需求 1:
实现搜索功能的伪静态化
//将注入路由的函数挂上接口
Add_Filter_Plugin('Filter_Plugin_Zbp_PreLoad', 'demoPlugin_RegRoute');
//创建搜索伪静化的规则,并挂在 Filter_Plugin_Zbp_PreLoad 接口
function demoPlugin_RegRoute()
{
global $zbp;
$route = array (
'posttype' => 0,//文章类型
'type' => 'rewrite',//路由的类型,可以是active,rewrite,default
'name' => 'post_article_search', //名称
'call' => 'ViewSearch', //呼叫的函数,匹配成功后call之,并传入一个含有各种匹配参数的数组
'urlrule' => '{%host%}search/{%q%}_{%page%}.html',//规则主体
'args' => //伪静类型路由的参数(出现在urlrule里的)
array (
'q' => '[^\\/_]+',//q是搜索的关键字,支持正则匹配
'page',//page是页码
),
'only_match_page' => false,//为假表示可以匹配没有{%page%}参数的url,默认如此可以不加这一行配置
);
$zbp->RegRoute($route);
}
//ViewSearch函数系统已经写好了,所以只需要注入路由就可以实现搜索功能的伪静态化!路由系统在匹配到规则后,向 call 所指定的函数 传入一个 array 数组,其格式如下
function ViewSearch() {
//获取路由系统传入参数,路由系统传入一个且只传一个含有各种匹配参数的数组
$args = func_get_arg(0);
$q = $args['q']; //获取查询字符串
$page = $args['page']; //获取页面,如果有的话
//得到该匹配成功的Route路由规则
$route = $args['_route'];
//可以打印出$args查看详情
var_dump($args);
/*
//该数组由posttype和匹配的各种参数和原始规则组成
array(4) {
["q"]=>
string(7) "xxxxxxx"
["page"]=>
int(1)
["posttype"]=>
int(0)
["_route"]=>
array(10) {
//路由规则。。。
//该段省略
}
}
*/
}例子 2(文章页专属下载页)
假定需求 2:
对于{%host%}post/{%id%}.html模式的访问,另外定义一条{%host%}download/{%id%}.html用于显示下载内容;
向ActivePlugin_demoPlugin()函数内添加如下接口挂载;
Add_Filter_Plugin('Filter_Plugin_Zbp_PreLoad', 'demoPlugin_RegRoute');接口函数定义:
//注册一条属于文章页的下载页面,并挂在 Filter_Plugin_Zbp_PreLoad 接口
function demoPlugin_RegRoute()
{
global $zbp;
$route = array(
// 默认取 0 即 article,建议显示设置,表示当前路由无论是单页还是列表都与该类型相关;
// 可按需设置 $GLOBALS['posttype'] 内的其他值,还可以自行添加类型,或者设置为 null 表示不属于任何类型;
'posttype' => 0, //0是文章
// 路由类型 (rewrite 类型使用 route 规则进行匹配,从规则中取得参数并传入 call,不匹配将跳出本规则进入下一条)
'type' => 'rewrite',
// 路由名称,推荐格式:前缀_路由功能
'name' => 'plugin_demoPlugin_download',
// 路由调用的函数
'call' => 'demoPlugin_ViewDownload',
// 动态路由和伪静路由的原始规则 (必须)
'urlrule' => '{%host%}download/{%id%}.html',
// 从伪静规则匹配到的数组中取值传给 call 的参数 (示例为 array('id', 'page') or array('cate@alias', 'page') )
'args' =>
array(
0 => 'post@id',
),
'verify_permalink' => false, //1.7.1新增参数,false时不比对当前url与目标url是否相同
);
$zbp->RegRoute($route);
}
// 对于路由匹配到的访问,会调用这个函数
function demoPlugin_ViewDownload($arg)
{
// $arg就是路由系统传入的数组参数,包含匹配到的参数和其它信息;
var_dump($arg);
$id = $arg["post"]; //获取文章的ID
//显示下载页面
//业务代码自行实现
}例子 3(文章页实现内容分页)
假定需求 3:
对文章内容分页,使用一条规则实现;
将'{%host%}post/{%id%}_{%page%}.html'改为'{%host%}post/{%id%}_{%all%}.html',由{%all%}匹配对应位置的内容;
接口函数定义:
function demoPlugin_RegRoute3()
{
global $zbp;
$route =
array(
'posttype' => 0,
'type' => 'rewrite',
'name' => 'plugin_demoPlugin_PostPagination',
'call' => 'demoPlugin_ViewPost',
'urlrule' => '{%host%}post/{%id%}_{%all%}.html',
'args' =>
array(
'post@id',
'all' => 'all|[0-9]+',
),
'verify_permalink' => false,//不比对当前url与目标url是否相同
);
$zbp->RegRoute($route);
return true;
}
function demoPlugin_ViewPost($arg)
{
// $arg就是路由系统传入的数组参数,包含匹配到的参数和其它信息;
var_dump($arg);
// 从数组获取指定下标的值
$id = $arg["post"]; //获取文章的ID
$isAll = $arg["all"];
if ($isAll == 'all') {
// 全文获取
// code
} else {
$page = $isAll;
// 将文章内容分页后获取第 $page 页;
// code
}
}例子 4(路由规则内实现跳转)
假定需求 4:
利用路由规则实现 301,302 跳转;
//路由规则如下,请用$zbp->RegRoute()注入路由系统就可以实现了
//此路由规则type是默认规则‘default’,伪静模式或动态模式,都可以生效!
$route = array(
'posttype' => 0,
'type' => 'default',
'name' => 'plugin_redierct_to_baidu',
'urlrule' => '{%host%}baidu.html',
// redirect_to是http302跳转,如果需要301跳转,键名要写为redirect301_to
'redirect_to' => 'https://www.baidu.com/',
);
$zbp->RegRoute($route, true);//这里需要加上第2个参数ture表示追加路由到最前
//访问https://网站/baidu.html 就会跳转到 https://www.baidu.com/例子 5(实现网站改版 301 跳转)
假定需求 5:
1.7.2 版本及以上支持
在网站改版之前,文章的固定链接格式为 https://网站/post/{%id%}.html
改版之后,文章的新 URL 格式为 https://网站/article/{%alias%}.html
//定义301重写规则并注入系统
$route = array(
'posttype' => 0,
'type' => 'rewrite',
'name' => 'plugin_post_article_redierct301',
'urlrule' => '{%host%}post/{%id%}.html',
'call' => 'post_article_redierct301',
'args' => array('id'),
);
$zbp->RegRoute($route);
//定义Call 函数并实现Http 301跳转
function post_article_redierct301($arg){
global $zbp;
$id = $arg["id"]; //获取文章的ID
$post = $zbp->GetPostByID($id);
//拼装新的链接URL
$url = $zbp->host . 'article/' . rawurlencode($post->Alias) . '.html';
//返回301跳转数据
return array('StatusCode' => 301, 'Location' => $url);
}例子 6(API 实现伪静 URL 访问)
假定需求 6:
1.7.2 版本及以上支持
默认的 API 访问为 https://网站/zb_system/api.php?mod=post&act=get&id=1
伪静态下可以实现 https://网站/api/post/get/?id=1
//定义API重写规则并注入系统
$zbp->RegRoute(
array (
'posttype' => null,
'type' => 'rewrite',
'name' => 'rewrite_api',
'call' => 'Rewrite_API',
'urlrule' => '{%host%}api/{%mod%}/{%act%}/',
'args' =>
array (
'mod' => '[_a-zA-Z0-9]+',
'act' => '[_a-zA-Z0-9]+',
),
)
);
//定义Call 函数
function Rewrite_API(){
global $zbp;
// 标记为 API 运行模式
defined('ZBP_IN_API') || define('ZBP_IN_API', true);
ApiCheckEnable();
foreach ($GLOBALS['hooks']['Filter_Plugin_API_Begin'] as $fpname => &$fpsignal) {
$fpname();
}
ApiCheckAuth(false, 'api');
ApiCheckLimit();
$GLOBALS['mods'] = array();
$GLOBALS['mods_allow'] = array();
$GLOBALS['mods_disallow'] = array();
$fpargs = func_get_arg(0);
$GLOBALS['mod'] = strtolower($fpargs['mod']);
$GLOBALS['act'] = strtolower($fpargs['act']);
// 载入系统和应用的 mod
ApiLoadMods($GLOBALS['mods']);
//进行Api白名单和黑名单的检查
ApiCheckMods($GLOBALS['mods_allow'], $GLOBALS['mods_disallow']);
ApiLoadPostData();
ApiVerifyCSRF();
// 派发 API
ApiDispatch($GLOBALS['mods'], $GLOBALS['mod'], $GLOBALS['act']);
}