
最近有小伙伴咨询如何在Typecho中实现路由,这里简单写一下。
首先,我们需要创建一个插件,就叫MyAction吧!D:
- 在usr/plugins文件夹创建MyAction文件夹
- 新建一个叫Plugin.php的文件,基本内容如下:
<?php
namespace TypechoPlugin\MyAction;
use Helper;
use Typecho\Plugin\PluginInterface;
use Typecho\Widget\Helper\Form;
/**
* MyAction 路由展示
* @package MyAction
* @author gogobody
* @version 1.0.0
* @link https://ijkxs.com
*
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
class Plugin implements PluginInterface
{
public static function activate(){}
public static function deactivate(){}
public static function config(Form $form){}
public static function personalConfig(Form $form){}
}
这是一个空的插件,里面什么也没有,接下来我们讲解如何实现路由。
在Typecho中主要有两种实现路由的方式:
1. addRoute($name, $url, $widget, $action = null, $after = null) 2. addAction($actionName, $widgetName)
这两种路由访问方式不同,具体可以往后看~
从参数widget可以看出,我们需要一个widget类。
接下来在同样的目录下新建一个Router.php文件,并实现Widget类,基本的内容如下:
namespace TypechoPlugin\MyAction;
use \Utils\Helper;
use \Typecho\{Widget, Db};
use Typecho\Cookie;
class Router extends Widget implements \Widget\ActionInterface
{
public function action(){}
}
好了,现在可以开始创建路由了。
回到Plugin.php,我们首先使用addRoute的方式添加路由。修改activate函数:
// 在顶部引入刚刚的路由文件
require_once 'Router.php';
...
const widgetName = 'TypechoPlugin\MyAction\Router';
public static function activate()
{
Helper::addRoute('first_api','/first', self::widgetName, 'firstApiFunc');
}
public static function deactivate()
{// 养成好习惯,插件禁用时卸载路由
Helper::removeRoute('first_api');
}
在上面的代码中,我们创建了一个名为first_api,访问方式为 域名/first 的路由,访问该路由将调用widget对应的函数 firstApiFunc。因此,接下来,我们需要在 widget 中实现该函数。
修改 Router.php:
class Router extends Widget implements \Widget\ActionInterface
{
public function firstApiFunc()
{
echo '我是通过路由添加的api,直接在网页上输出!';
}
public function action()
}
这样,一个基本的路由就创建完成了!访问一下试试~

我们刚刚实现了第一种路由,接下来讲讲如何实现第二种路由,即使用action的方式实现。
继续修改Plugin.php
public static function activate()
{
Helper::addRoute('first_api','/first', self::widgetName, 'firstApiFunc');
Helper::addAction('use_action',self::widgetName);
}
public static function deactivate()
{// 养成好习惯,插件禁用时卸载路由
Helper::removeRoute('first_api');
Helper::removeAction('use_action');
}
在上面的代码中,我们添加了一个 action 映射到我们的widget。与使用addRoute的访问方式不同,action请求网址为: 域名/action/use_action
需要注意的是:使用action方式必须让类实现 implements \Widget\ActionInterface 接口,这个接口就一个action函数。
添加了action之后我们还需要添加对应的动作,就像拍电影,导演喊完action!演员总要有剧本才能继续往下演。
我们来添加一下剧本!修改Router.php
public function action()
{
$this->on($this->request->is('do=test'))->test_what_ever();
}
public function test_what_ever()
{
echo '我是通过action添加的api,通过访问action输出';
}
在上面的函数中,我们为action 添加了一个剧本,当有人访问 域名/action/use_action?do=test 的时候,去执行 test_what_ever 函数。(这里以get请求为例,post也可以实现,这里仅举例,不多扩展,有问题可以留言。)
访问一下试试~

到这为止,两种路由实现都讲完了,但现在的接口基本都是以json方式返回数据,方面做前后端分离。举两个例子。
第一个,通过cookie实现刷新计数(以addRoute实现)。
public static function activate()
{
Helper::addRoute('second_api','/second', self::widgetName, 'secondApiFunc');
}
public static function deactivate()
{
Helper::removeRoute('second_api');
}
代码前面都讲过了,不多说,现在实现一下secondApiFunc。
class Router extends Widget implements \Widget\ActionInterface
{
public function secondApiFunc()
{
$cnt = Cookie::get('my_count'); // 获取一下 my_count 对应值
if (isset($cnt)){ // 有值的话
$cnt = $cnt+1; // 值+1
Cookie::set('my_count', $cnt); // 重新存回 cookie
$data = json_encode([ // 把一个数组转成 json 字符串
'data' => ['cnt'=>$cnt],
'ret' => 1 // 获取成功
]);
} else{ // 没有值就初始化一个值
Cookie::set('my_count', 0);
$data = json_encode([
'data' => ['cnt'=>0],
'ret' => 0 // 获取失败
]);
}
die($data); // 输出到网页
}
}
访问一下试试咯,刷新一下 cnt 加一!

第二个,根据名字获取用户信息(action实现)
我们可以在同一个action下面添加动作(剧本),这次不用修改 Plugin.php了
// Plugin.php 的内容和上面讲action那部分一样
public static function activate()
{
Helper::addRoute('first_api','/first', self::widgetName, 'firstApiFunc');
Helper::addAction('use_action',self::widgetName);
}
public static function deactivate()
{// 养成好习惯,插件禁用时卸载路由
Helper::removeRoute('first_api');
Helper::removeAction('use_action');
}
在 Router.php 中添加动作。
public function action()
{
$this->on($this->request->is('do=test'))->test_what_ever();
$this->on($this->request->is('do=getUser'))->getUser();
}
public function getUser()
{
$name = $this->request->get('name'); // 获取参数name
$data = [];
$ret = [
'ret' => 1,
'msg' => '',
];
if (isset($name)){ // 如果参数存在
switch ($name){ // 根据值做一些事情
case 'bob':
$data['name'] = 'bob';
$data['age'] = 20;
break;
case 'jim':
$data['name'] = 'jim';
$data['age'] = 24;
break;
default: // 当上面条件都不满足
$data['ret'] = 0;
$data['msg'] = '没有找到对应信息';
}
$ret['data'] = $data;
echo json_encode($ret); // 打印json 化的数组
die(); // 内容输出到网页
}
$data['ret'] = 0;
$data['msg'] = '缺少参数';
$ret['data'] = $data;
echo json_encode($ret);
die();
}
在访问下看看~


到这基本上就写完了,感谢您的耐心观看。