• thinkPHP定义路由


    URL地址里面的index模块怎么才能省略呢,默认的URL地址显得有点长,下面就来说说如何通过路由简化URL访问。

    我们在路由定义文件(application/route.php)里面添加一些路由规则,如下:

    return [
        // 添加路由规则 路由到 index控制器的hello操作方法
        'hello/:name' => 'index/index/hello',
    ];
    

    该路由规则表示所有hello开头的并且带参数的访问都会路由到index控制器的hello操作方法。

    路由之前的URL访问地址为:

    http://tp5.com/index/index/hello/name/thinkphp
    

    定义路由后就只能访问下面的URL地址

    http://tp5.com/hello/thinkphp
    

    注意


    定义路由规则后,原来的URL地址将会失效,变成非法请求。

    但这里有一个小问题,如果我们只是访问

    http://tp5.com/hello
    

    将发生错误,

    事实上这是由于路由没有正确匹配到,我们修改路由规则如下:

    return [
        // 路由参数name为可选
        'hello/[:name]' => 'index/hello',
    ];
    

    使用[]把路由规则中的变量包起来,就表示该变量为可选,接下来就可以正常访问了。

    http://tp5.com/hello
    

    name参数没有传入值的时候,hello方法的name参数有默认值World,所以输出的内容为 Hello,World!

    除了路由配置文件中定义之外,还可以采用动态定义路由规则的方式定义,例如在路由配置文件(application/route.php)的开头直接添加下面的方法:

    use thinkRoute;
    
    Route::rule('hello/:name', 'index/hello');
    

    完成的效果和使用配置方式定义是一样的。

    无论是配置方式还是通过Route类的方法定义路由,都统一放到路由配置文件application/route.php文件中,具体原因后面会揭晓。

    提示:


    注意路由配置不支持在模块配置文件中设置。

    完整匹配

    前面定义的路由是只要以hello开头就能进行匹配,如果需要完整匹配,可以使用下面的定义:

    return [
        // 路由参数name为可选
        'hello/[:name]$' => 'index/hello',
    ];
    

    当路由规则以$结尾的时候就表示当前路由规则需要完整匹配。

    当我们访问下面的URL地址的时候:

    http://tp5.com/hello // 正确匹配
    http://tp5.com/hello/thinkphp // 正确匹配
    http://tp5.com/hello/thinkphp/val/value // 不会匹配
    

    闭包定义

    还支持通过定义闭包为某些特殊的场景定义路由规则,例如:

    return [
        // 定义闭包
        'hello/[:name]' => function ($name) {
            return 'Hello,' . $name . '!';
        },
    ];
    

    或者

    use thinkRoute;
    
    Route::rule('hello/:name', function ($name) {
        return 'Hello,' . $name . '!';
    });
    

    提示:


    闭包函数的参数就是路由规则中定义的变量。

    因此,当访问下面的URL地址:

    http://tp5.com/hello/thinkphp
    

    会输出

    Hello,thinkphp!
    

    设置URL分隔符

    如果需要改变URL地址中的pathinfo参数分隔符,只需要在应用配置文件(application/config.php)中设置:

    // 设置pathinfo分隔符
    'pathinfo_depr'          => '-',
    

    路由规则定义无需做任何改变,我们就可以访问下面的地址:

    http://tp5.com/hello-thinkphp
    

    路由参数

    我们还可以约束路由规则的请求类型或者URL后缀之类的条件,例如:

    return [
        // 定义路由的请求类型和后缀
        'hello/[:name]' => ['index/hello', ['method' => 'get', 'ext' => 'html']],
    ];
    

    上面定义的路由规则限制了必须是get请求,而且后缀必须是html的,所以下面的访问地址:

    http://tp5.com/hello // 无效
    http://tp5.com/hello.html // 有效
    http://tp5.com/hello/thinkphp // 无效
    http://tp5.com/hello/thinkphp.html // 有效
    

    更多的路由参数请参考完全开发手册的路由参数一节。

    变量规则

    接下来,我们来尝试一些复杂的路由规则定义满足不同的路由变量。在此之前,首先增加一个控制器类如下:

    <?php
    
    namespace appindexcontroller;
    
    class Blog
    {
    
        public function get($id)
        {
            return '查看id=' . $id . '的内容';
        }
    
        public function read($name)
        {
            return '查看name=' . $name . '的内容';
        }
    
        public function archive($year, $month)
        {
            return '查看' . $year . '/' . $month . '的归档内容';
        }
    }
    

    添加如下路由规则:

    return [
        'blog/:year/:month' => ['blog/archive', ['method' => 'get'], ['year' => 'd{4}', 'month' => 'd{2}']],
        'blog/:id'          => ['blog/get', ['method' => 'get'], ['id' => 'd+']],
        'blog/:name'        => ['blog/read', ['method' => 'get'], ['name' => 'w+']],
    ];
    

    在上面的路由规则中,我们对变量进行的规则约束,变量规则使用正则表达式进行定义。

    我们看下几种URL访问的情况

    // 访问id为5的内容
    http://tp5.com/blog/5 
    // 访问name为thinkphp的内容
    http://tp5.com/blog/thinkphp 
    // 访问2015年5月的归档内容
    http://tp5.com/blog/2015/05 
    

    路由分组

    上面的三个路由规则由于都是blog打头,所以我们可以做如下的简化:

    return [
        '[blog]' => [
            ':year/:month' => ['blog/archive', ['method' => 'get'], ['year' => 'd{4}', 'month' => 'd{2}']],    
            ':id'          => ['blog/get', ['method' => 'get'], ['id' => 'd+']],
            ':name'        => ['blog/read', ['method' => 'get'], ['name' => 'w+']],
        ],
    ];
    

    对于这种定义方式,我们称之为路由分组,路由分组一定程度上可以提高路由检测的效率。

    复杂路由

    有时候,我们还需要对URL做一些特殊的定制,例如如果要同时支持下面的访问地址

    http://tp5.com/blog/thinkphp 
    http://tp5.com/blog-2015-05 
    

    我们只要稍微改变路由定义规则即可:

    return [
        'blog/:id'            => ['blog/get', ['method' => 'get'], ['id' => 'd+']],
        'blog/:name'          => ['blog/read', ['method' => 'get'], ['name' => 'w+']],
        'blog-<year>-<month>' => ['blog/archive', ['method' => 'get'], ['year' => 'd{4}', 'month' => 'd{2}']],
    ];
    

    对 blog-<year>-<month> 这样的非正常规范,我们需要使用<变量名>这样的变量定义方式,而不是 :变量名方式。

    简单起见,我们还可以把变量规则统一定义,例如:

    return [
        // 全局变量规则定义
        '__pattern__'         => [
            'name'  => 'w+',
            'id'    => 'd+',
            'year'  => 'd{4}',
            'month' => 'd{2}',
        ],
        // 路由规则定义
        'blog/:id'            => 'blog/get',
        'blog/:name'          => 'blog/read',
        'blog-<year>-<month>' => 'blog/archive',
    ];
    

    __pattern__中定义的变量规则我们称之为全局变量规则,在路由规则里面定义的变量规则我们称之为局部变量规则,如果一个变量同时定义了全局规则和局部规则的话,当前的局部规则会覆盖全局规则的,例如:

    return [
        // 全局变量规则
        '__pattern__'         => [
            'name'  => 'w+',
            'id'    => 'd+',
            'year'  => 'd{4}',
            'month' => 'd{2}',
        ],
    
        'blog/:id'            => 'blog/get',
        // 定义了局部变量规则
        'blog/:name'          => ['blog/read', ['method' => 'get'], ['name' => 'w{5,}']],
        'blog-<year>-<month>' => 'blog/archive',
    ];
    

    【 5.1 】使用须知


    5.1的路由配置文件改为route/route.php,并且支持随意命名,都会自动加载。并尽量使用方法注册路由的方式替代数组配置的方式,例如。

    use thinkfacadeRoute;
    
    Route::get('blog/:id','blog/get');
    Route::get('blog/:name','blog/read');
  • 相关阅读:
    [BZOJ2809][Apio2012]dispatching
    [BZOJ4584][Apio2016]赛艇
    [BZOJ3206][Apio2013]道路费用
    [codeforces551E]GukiZ and GukiZiana
    [BZOJ3809]Gty的二逼妹子序列
    [BZOJ3289]Mato的文件管理
    [BZOJ3052][UOJ#58][WC2013]糖果公园
    [SPOJ10707]Count on a tree II
    [BZOJ1086][SCOI2005]王室联邦
    python小知识
  • 原文地址:https://www.cnblogs.com/xu1115/p/10977620.html
Copyright © 2020-2023  润新知