TP5.0路由和URL

框架 专栏收录该内容
8 篇文章 0 订阅

上一篇文章介绍了tp5.0的目录架构和数据库的简单操作。关于数据库操作这方面我会在其他文章详细介绍。这篇文章我们主要谈一下路由和url。



首先我们要知道ThinkPHP采用单一入口模式访问应用,对应用的所有请求都定向到应用的入口文件,系统会从URL参数中解析当前请求的模块、控制器和操作,下面是一个标准的URL访问格式:
http://域名/index.php/模块/控制器/方法

其中index.php是入口文件,我们可以通过配置web服务器的重写规则将其隐藏。

以Apache为例,我们需要在入口文件的同级添加.htaccess文件(官方默认自带了该文件),内容如下:

<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

如果用的phpstudy,规则如下:

<IfModule mod_rewrite.c> 
Options +FollowSymlinks -Multiviews 
RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1] 
</IfModule>

配置完成后我们就可以使用下面这样的url地址进行访问了:
http://域名/index.php/模块/控制器/方法

如果你使用的apache版本使用上面的方式无法正常隐藏index.php,可以尝试使用下面的方式配置.htaccess文件:

<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>

如果是Nginx环境的话,可以在Nginx.conf中添加:

location / { // …..省略部分代码
    if (!-e $request_filename) {
        rewrite  ^(.*)$  /index.php?s=/$1  last;
        break;
    }
}

个人在rewrite方面比较薄弱,更多nginx的rewrite用法请参考https://segmentfault.com/a/1190000008102599

//模块在ThinkPHP中的概念其实就是应用目录下面的子目录,而官方的规范是目录名小写,因此模块全部采用小写命名,无论URL是否开启大小写转换,模块名都会强制小写。

默认情况下,URL地址中的控制器和操作名是不区分大小写的,但是如果要访问一个驼峰命名的控制器,例如我们在index模块下创建一个HelloWorld类文件:

class HelloWorld
{
        public function index()
        {
            echo 'hello , world !';
        }

}

这时候我们的访问方式默认为:
http://域名/Index/hello_world/index
而使用http://域名/Index/HelloWorld/index这种方式的访问则会报一个找不到控制器的错误。因为默认的URL访问是不区分大小写的,全部都会转换为小写的控制器名,除非你在应用配置文件中,设置了关闭url自动转换如下:

//设置url中控制器和操作名自动转换关闭
'url_convert'   => false,

这样的话我们就可以通过驼峰的方式正常访问。操作方法的访问本身不会受到自动转换的影响,但是却会影响到默认模板的渲染输出。如图:

驼峰命名导致的视图层异常

这样的话我们会得到一个找不到视图文件的错误,解决方案有两种:

  1. 将视图文件目录命名为hello_world这种形式。
  2. 在模版渲染输出时指定视图文件的名称 $this -> fetch('HelloWorld/index');

// 控制器名称必须按照规范,否则会无法访问

官方文档说:关闭URL自动转换之后,必须使用下面的URL地址访问(控制器名称必须严格使用控制器类的名称,不包含控制器后缀)。 但实操发现使用hello_world这种访问方法依然是可以访问的。
关闭url自动转换后并不影响访问



如果你的服务器环境不支持pathinfo方式的URL访问,可以使用兼容方式,例如:
http://域名/index.php?s=index/hello_world/index

变量 S 是可以在应用目录下的配置文件中配置的
默认的访问模块也可以在应用目录下的配置文件中配置

5.0版本不再支持普通的url访问方式。例如:http://域名/index.php?m=index&c=hellow_world&a=index

定义路由

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',
];

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

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

use think\Route;
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 // 不会匹配

关于路由就简单写到这里,更加复杂的设置请参见[tp5.0完全开发手册]

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值