Home > Backend Development > PHP Tutorial > Detailed examples of thinkphp5 URL and routing functions

Detailed examples of thinkphp5 URL and routing functions

小云云
Release: 2023-03-18 16:24:02
Original
3618 people have browsed it

This article mainly introduces the detailed explanation and examples of thinkphp5 URL and routing functions. The editor thinks it is quite good, so I will share it with you now and give it as a reference. Let’s follow the editor to take a look, I hope it can help everyone.

URL access

ThinkPHP uses a single entry mode to access the application. All requests for the application are directed to the application's entry file, and the system will retrieve the application from the URL parameters. Parse the module, controller and operation of the current request. The following is a standard URL access format:


http://domainName/index.php/模块/控制器/操作
Copy after login

where index.php is called the entry file of the application (note The entry file can be hidden, which will be mentioned later)

The concept of a module in ThinkPHP is actually a subdirectory under the application directory, and the official specification is that the directory name is lowercase, so the modules are all named in lowercase, regardless of the URL. Whether case conversion is enabled, the module name will be forced to lowercase.

The Index controller of the applied index module is defined as follows:


<?php
namespace app\index\controller;
class Index
{
  public function index()
  {
    return &#39;index&#39;;
  }
  public function hello($name = &#39;World&#39;)
  {
    return &#39;Hello,&#39; . $name . &#39;!&#39;;
  }
}
Copy after login
Copy after login

If the entry file is directly accessed , since there are no modules, controllers and operations in the URL, the system will access the default operation (index) of the default controller (Index) under the default module (index), so the following accesses are equivalent:

http://tp5.com/index.php
http://tp5.com/index.php/index/index/index

If you want to access the hello method of the controller, you need to use Complete URL address

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

After accessing the URL address, the page output result is:

Hello, thinkphp!

Since the name parameter is an optional parameter, you can also use

http://tp5.com/index.php/index/index/hello

After accessing the URL address, the page output result is:

Hello, World!

By default, the controller and operation names in the URL address are not case-sensitive, so the following The access is actually equivalent:

http://tp5.com/index.php/index/Index/Index
http://tp5.com/index.php/index/INDEX/ INDEX

If the controller is camelCase, for example, define a HelloWorld controller (application/index/controller/HelloWorld.php):


<?php
namespace app\index\controller;
class HelloWorld
{
  public function index($name = &#39;World&#39;)
  {
    return &#39;Hello,&#39; . $name . &#39;!&#39;;
  }
}
Copy after login

Correct The URL access address (the address can be generated using the url method) should be

http://tp5.com/index.php/index/hello_world/index

The system will automatically locate the HelloWorld control Device class to operate

If you use

http://tp5.com/index.php/index/HelloWorld/index

, an error will be reported and the Helloworld controller will be prompted. Class does not exist

If you want strict case-sensitive access (so that you can support camel case for controller access), you can set it in the application configuration file:


// 关闭URL自动转换(支持驼峰访问控制器)
&#39;url_convert&#39; => false,
Copy after login

After turning off URL automatic conversion, you must use the following URL address to access (the controller name must strictly use the name of the controller class, excluding the controller suffix):

http://tp5.com/ index.php/index/Index/index
http://tp5.com/index.php/index/HelloWorld/index

If the server environment does not support pathinfo URL access, you can use the compatibility method , for example:

http://tp5.com/index.php?s=/index/Index/index

The name of the variable s can be configured

5.0 no longer supports ordinary URL access methods, so the following access is invalid. You will find that no matter what you enter, you will access the default controller and operation

http://tp5.com/index .php?m=index&c=Index&a=hello

Parameters passed in

Through the parameter binding function of the operation method, the parameters of the URL can be automatically obtained , still taking the above controller as an example, the controller code is as follows:


<?php
namespace app\index\controller;
class Index
{
  public function index()
  {
    return &#39;index&#39;;
  }
  public function hello($name = &#39;World&#39;)
  {
    return &#39;Hello,&#39; . $name . &#39;!&#39;;
  }
}
Copy after login
Copy after login

When we visit

http://tp5.com/index. php/index/index/hello

is to access the hello method of the app\index\controller\Index controller class. Because no parameters are passed in, the name parameter uses the default value World. If the name parameter is passed in, use:

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

The page output result is:

Hello, thinkphp!

Now add a second parameter to the hello method:


public function hello($name = &#39;World&#39;, $city = &#39;&#39;)
  {
    return &#39;Hello,&#39; . $name . &#39;! You come from &#39; . $city . &#39;.&#39;;
  }
Copy after login

The access address is http://tp5.com/ The output result of index.php/index/index/hello/name/thinkphp/city/shanghai

is:

Hello, thinkphp! You come from shanghai.

Okay As you can see, the hello method will automatically obtain the parameter value with the same name in the URL address as the parameter value of the method, and the order in which this parameter is passed is not affected by the order of the URL parameters. For example, the output result of the following URL address is the same as the above:

http://tp5.com/index.php/index/index/hello/city/shanghai/name/thinkphp

Or use http://tp5.com/index.php /index/index/hello?city=shanghai&name=thinkphp

The URL address can be further simplified. The premise is that we must clarify the variables represented by the order of the parameters. We change the way to obtain the URL parameters and apply The value of the url_param_type parameter in the configuration file is modified as follows:


// 按照参数顺序获取
&#39;url_param_type&#39; => 1,
Copy after login

现在,URL的参数传值方式就变成了严格按照操作方法的变量定义顺序来传值了,也就是说我们必须使用下面的URL地址访问才能正确传入name和city参数到hello方法:http://tp5.com/index.php/index/index/hello/thinkphp/shanghai

页面输出结果为:

Hello,thinkphp! You come from shanghai.

如果改变参数顺序为http://tp5.com/index.php/index/index/hello/shanghai/thinkphp

页面输出结果为:

Hello,shanghai! You come from thinkphp.

显然不是我们预期的结果。

同样,我们试图通过http://tp5.com/index.php/index/index/hello/name/thinkphp/city/shanghai

访问也不会得到正确的结果

[注意]按顺序绑定参数的话,操作方法的参数只能使用URL pathinfo变量,而不能使用get或者post变量

隐藏入口

可以去掉URL地址里面的入口文件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>
Copy after login

如果用的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>
Copy after login

接下来就可以使用下面的URL地址访问了

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

如果使用的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>
Copy after login

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


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

定义路由

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

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


return [
  // 添加路由规则 路由到 index控制器的hello操作方法
  &#39;hello/:name&#39; => &#39;index/index/hello&#39;,
];
Copy after login

该路由规则表示所有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为可选
  &#39;hello/[:name]&#39; => &#39;index/hello&#39;,
];
Copy after login

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

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

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


use think\Route;
Route::rule(&#39;hello/:name&#39;, &#39;index/hello&#39;);
Copy after login

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

无论是配置方式还是通过Route类的方法定义路由,都统一放到路由配置文件application/route.php文件中

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

【完整匹配】

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


return [
  // 路由参数name为可选
  &#39;hello/[:name]$&#39; => &#39;index/hello&#39;,
];
Copy after login

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

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

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

【闭包定义】

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


return [
  // 定义闭包
  &#39;hello/[:name]&#39; => function ($name) {
    return &#39;Hello,&#39; . $name . &#39;!&#39;;
  },
];
Copy after login

或者


use think\Route;
Route::rule(&#39;hello/:name&#39;, function ($name) {
  return &#39;Hello,&#39; . $name . &#39;!&#39;;
});
Copy after login

[注意]闭包函数的参数就是路由规则中定义的变量

因此,当访问下面的URL地址:http://tp5.com/hello/thinkphp

会输出

Hello,thinkphp!

【设置URL分隔符】

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


// 设置pathinfo分隔符
&#39;pathinfo_depr&#39;     => &#39;-&#39;,
Copy after login

路由规则定义无需做任何改变,我们就可以访问下面的地址:http://tp5.com/hello-thinkphp

【路由参数】

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


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

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

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

【变量规则】

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


<?php
namespace app\index\controller;
class Blog
{
  public function get($id)
  {
    return &#39;查看id=&#39; . $id . &#39;的内容&#39;;
  }
  public function read($name)
  {
    return &#39;查看name=&#39; . $name . &#39;的内容&#39;;
  }
  public function archive($year, $month)
  {
    return &#39;查看&#39; . $year . &#39;/&#39; . $month . &#39;的归档内容&#39;;
  }
}
Copy after login

添加如下路由规则:


return [
  &#39;blog/:year/:month&#39; => [&#39;blog/archive&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;year&#39; => &#39;\d{4}&#39;, &#39;month&#39; => &#39;\d{2}&#39;]],
  &#39;blog/:id&#39;     => [&#39;blog/get&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;id&#39; => &#39;\d+&#39;]],
  &#39;blog/:name&#39;    => [&#39;blog/read&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;name&#39; => &#39;\w+&#39;]],
];
Copy after login

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

我们看下几种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 [
  &#39;[blog]&#39; => [
    &#39;:year/:month&#39; => [&#39;blog/archive&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;year&#39; => &#39;\d{4}&#39;, &#39;month&#39; => &#39;\d{2}&#39;]],  
    &#39;:id&#39;     => [&#39;blog/get&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;id&#39; => &#39;\d+&#39;]],
    &#39;:name&#39;    => [&#39;blog/read&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;name&#39; => &#39;\w+&#39;]],
  ],
];
Copy after login

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

【复杂路由】

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

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

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


return [
  &#39;blog/:id&#39;      => [&#39;blog/get&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;id&#39; => &#39;\d+&#39;]],
  &#39;blog/:name&#39;     => [&#39;blog/read&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;name&#39; => &#39;\w+&#39;]],
  &#39;blog-<year>-<month>&#39; => [&#39;blog/archive&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;year&#39; => &#39;\d{4}&#39;, &#39;month&#39; => &#39;\d{2}&#39;]],
];
Copy after login

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

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


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

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


return [
  // 全局变量规则
  &#39;__pattern__&#39;     => [
    &#39;name&#39; => &#39;\w+&#39;,
    &#39;id&#39;  => &#39;\d+&#39;,
    &#39;year&#39; => &#39;\d{4}&#39;,
    &#39;month&#39; => &#39;\d{2}&#39;,
  ],

  &#39;blog/:id&#39;      => &#39;blog/get&#39;,
  // 定义了局部变量规则
  &#39;blog/:name&#39;     => [&#39;blog/read&#39;, [&#39;method&#39; => &#39;get&#39;], [&#39;name&#39; => &#39;\w{5,}&#39;]],
  &#39;blog-<year>-<month>&#39; => &#39;blog/archive&#39;,
];
Copy after login

URL生成

定义路由规则之后,可以通过Url类来方便的生成实际的URL地址(路由地址),针对上面的路由规则,我们可以用下面的方式生成URL地址。


// 输出 blog/thinkphp
Url::build(&#39;blog/read&#39;, &#39;name=thinkphp&#39;);
Url::build(&#39;blog/read&#39;, [&#39;name&#39; => &#39;thinkphp&#39;]);
// 输出 blog/5
Url::build(&#39;blog/get&#39;, &#39;id=5&#39;);
Url::build(&#39;blog/get&#39;, [&#39;id&#39; => 5]);
// 输出 blog/2015/05
Url::build(&#39;blog/archive&#39;, &#39;year=2015&month=05&#39;);
Url::build(&#39;blog/archive&#39;, [&#39;year&#39; => &#39;2015&#39;, &#39;month&#39; => &#39;05&#39;]);
Copy after login

[注意]build方法的第一个参数使用路由定义中的完整路由地址

还可以使用系统提供的助手函数url来简化


url(&#39;blog/read&#39;, &#39;name=thinkphp&#39;);
// 等效于
Url::build(&#39;blog/read&#39;, &#39;name=thinkphp&#39;);
Copy after login

通常在模板文件中输出的话,可以使用助手函数,例如:


{:url(&#39;blog/read&#39;, &#39;name=thinkphp&#39;)}
Copy after login

如果我们的路由规则发生调整,生成的URL地址会自动变化

如果你配置了url_html_suffix参数的话,生成的URL地址会带上后缀,例如:


&#39;url_html_suffix&#39;  => &#39;html&#39;,
Copy after login

那么生成的URL地址 类似


blog/thinkphp.html 
blog/2015/05.html
Copy after login

如果你的URL地址全部采用路由方式定义,也可以直接使用路由规则来定义URL生成,例如:


url(&#39;/blog/thinkphp&#39;);
Url::build(&#39;/blog/8&#39;);
Url::build(&#39;/blog/archive/2015/05&#39;);
Copy after login

生成方法的第一个参数一定要和路由定义的路由地址保持一致,如果你的路由地址比较特殊,例如使用闭包定义的话,则需要手动给路由指定标识,例如:


// 添加hello路由标识
Route::rule([&#39;hello&#39;,&#39;hello/:name&#39;], function($name){
  return &#39;Hello,&#39;.$name;
});
// 根据路由标识快速生成URL
Url::build(&#39;hello&#39;, &#39;name=thinkphp&#39;);
// 或者使用
Url::build(&#39;hello&#39;, [&#39;name&#39; => &#39;thinkphp&#39;]);
Copy after login

相关推荐:

实例分享Thinkphp5行为使用方法

实例讲解thinkphp5 加载静态资源路径与常量的示例

Thinkphp5+PHPExcel实现批量上传表格数据功能_php实例

The above is the detailed content of Detailed examples of thinkphp5 URL and routing functions. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template