自定义路由

BeaconPHP 的路由规则是允许自定义的,要自定义路由我们需要用到 Route 路由类。

一个自定义路由的完整代码如下。

use beacon\core\App;
use beacon\core\Route;

#设置时区
date_default_timezone_set('PRC');
###开发可打开调试模式,上线时一定要关闭
const DEV_DEBUG = true;
#调试日志输出
const DEBUG_LOG = true;
#调试sql语句输出
const DEBUG_MYSQL_LOG = true;
#使用 REDIS_SESSION
const USE_REDIS_SESSION = false;
#定义根目录
define('ROOT_DIR', dirname(__DIR__));
#以上定义常量---------

#引入composer 启动文件
require(ROOT_DIR . '/vendor/autoload.php');

#定义路由

$route = new Route('home', '/');
$route->addRule([
    #键名是一个正则表达式,值是一个数组,其中 $1 $2 .. 表示从表达式括号中抽取相应的内容。 除了必须要设置 ctl act 以外 还可以设置其他参数,其他参数将写入到 $_GET  中。
    #如这个表达式是请求路径 /abc/32333  执行的是 控制器 index 操作 index 参数 id=32333
    '@^/abc/(\d+)@' => ['ctl' => 'index', 'act' => 'index', 'id' => '$1'],
    #这个表达式是 请求 / 执行的控制器是 index 操作是 index
    '@^/@' => ['ctl' => 'index', 'act' => 'index']
]);
App::reg($route);

App::route('admin', '/admin');
App::route('service', '/service');
#运行应用
App::run();


 

约定:

其中 ctl 和 act 在路由规则定义中 必须指定,可以是 替换符  $1 $2  $... zi取表达式括号中的内容。

ctl 不可以使用大写 如果控制器是 MyBook  对应的小写+下划线 是  my_book

如果是Mybook对应的是mybook

操作act也不能使用大写,只能是小写+下划线。


自定义路由在项目中如果不是特殊要求,一般不会去自定义,为了性能考虑,直接使用正则表达式来定义,这里设计没有使用其他路由定义的符号定义,主要是考虑到性能问题。

 

自定义路由的URL生成

由于自定义路由,所以对于虚拟URL转换到真实的URL 默认的转换规则已经不再适用,所以我们这里需要设置一个转换函数用于生成对应的模板URL

注意生成的是 URL 的模板而不是url 本身

如:

/{ctl}/{act}/{id} 或者 /{ctl}/{act}_{id} 这个是URL模板

我们需要设置一个用于生成URL模板的方法。

function (string $ctl, string $act, array $param)


$ctl 是控制器,$act 是操作,$param 是参数键值对

例如 我们默认的规则是

function (string $ctl, string $act, array $param) {
    $url = '/{ctl}';
    if (!empty($act) && $act != 'index') {
        $url .= '/{act}';
    }
    return $url;
}
# 即如果有控制器和操作名称 就返回 /{ctl}/{act}  
# 如果只有控制器没有操作名称 就返回 /{ctl}     


那么依据上面我们自定义的路由规则

我们希望 如果是 ctl == index   ,act == index (或者为空) 且 有 id存在的时候  url 反解析为 /abc/{id}
如果没有 id 的时候 直接返回 /

反解析生成URL模板函数如下:

function (string $ctl, string $act, array $param) {
    if ($ctl == 'index' && (empty($act) || $act == 'index') && isset($param['id'])) {
        return '/abc/{id}';
    }
    return '/';
}



完整的路由代码如下:

use beacon\core\App;
use beacon\core\Route;

#设置时区
date_default_timezone_set('PRC');
###开发可打开调试模式,上线时一定要关闭
const DEV_DEBUG = true;
#调试日志输出
const DEBUG_LOG = true;
#调试sql语句输出
const DEBUG_MYSQL_LOG = true;
#使用 REDIS_SESSION
const USE_REDIS_SESSION = false;
#定义根目录
define('ROOT_DIR', dirname(__DIR__));
#以上定义常量---------

#引入composer 启动文件
require(ROOT_DIR . '/vendor/autoload.php');

#定义路由

$route = new Route('home', '/');
$route->addRule([
    #键名是一个正则表达式,值是一个数组,其中 $1 $2 .. 表示从表达式括号中抽取相应的内容。 除了必须要设置 ctl act 以外 还可以设置其他参数,其他参数将写入到 $_GET  中。
    #如这个表达式是请求路径 /abc/32333  执行的是 控制器 index 操作 index 参数 id=32333
    '@^/abc/(\d+)@' => ['ctl' => 'index', 'act' => 'index', 'id' => '$1'],
    #这个表达式是 请求 / 执行的控制器是 index 操作是 index
    '@^/@' => ['ctl' => 'index', 'act' => 'index']
]);
#设置反解析URL函数,返回的是URL模板
$route->setResolve(function (string $ctl, string $act, array $param) {
    if ($ctl == 'index' && (empty($act) || $act == 'index') && isset($param['id'])) {
        return '/abc/{id}';
    }
    return '/';
});

App::reg($route);

App::route('admin', '/admin');
App::route('service', '/service');
#运行应用
App::run();



设置好反解析后:

class Index extends Controller
{
    /**
     * 使用模板
     * @return string
     */
    #[Method(act: 'index', method: Method::GET)]
    public function index()
    {
        echo App::url(['ctl' => 'index', 'act' => 'index', 'id' => 3, 'name' => 'wj008']) . '</br>';
        echo App::url(['ctl' => 'index', 'act' => 'index', 'name' => 'wj008']) . '</br>';
    }

}



最终生成的真实URL 如下:

/abc/3?name=wj008
/?name=wj008



上一篇:路由设置
下一篇:生成URL
Copyright © 2021 海南的叶子 All Rights Reserved 琼ICP备2021000725号

琼公网安备 46900702000037号