Thinkphp5 URL and routing features in detail and examples

Source: Internet
Author: User
Tags closure definition
This article mainly introduces the THINKPHP5 URL and routing of the functional details and examples, small series feel very good, and now share to everyone, but also for everyone to do a reference. Let's take a look at it with a little knitting.

Previous words

This article will detail the Thinkphp5url and routing

URL Access

Thinkphp uses a single-entry mode to access the app, directing all requests to the app to the app's portal file, which resolves the currently requested module, controller, and operation from the URL parameters, and a standard URL access format:


http://domainName/index.php/module/Controller/operation

Where index.php is called the application's entry file (note that the entry file can be hidden, as mentioned later)

The concept of the module in the thinkphp is actually the subdirectory under the application directory, and the official specification is the directory name lowercase, so the module is all lowercase named, regardless of whether the URL is turned on case conversion, the module name will force lowercase

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


<?php
namespace app\index\controller;
class Index
{
  public function index()
  {
    return 'index';
  }
  public function hello($name = 'World')
  {
    return 'Hello,' . $name . '!';
  }
}

If you access the portal file directly, because there are no modules, controllers, and actions in the URL, the default action (index) for the default controller (index) under the default module (index) is accessed, so the following access is equivalent:

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

If you want to access the controller's Hello method, you need to use the full URL address

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

After accessing the URL address, the page output is:

hello,thinkphp!

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

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

After accessing the URL address, the page output is:

hello,world!

By default, the controller and operation names in the URL address are case insensitive, so the following accesses are actually equivalent:

Http://tp5.com/index.php/index/Index/Index

Http://tp5.com/index.php/index/INDEX/INDEX

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


<?php
namespace app\index\controller;
class HelloWorld
{
  public function index($name = 'World')
  {
    return 'Hello,' . $name . '!';
  }
}

The correct URL access address (which can be generated using the URL method) should be

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

The system will automatically navigate to the HelloWorld controller class to operate

If you use

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

Will error and prompt HelloWorld controller class does not exist

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



// turn off automatic URL conversion (support camel access controller)
'url_convert' => false,

After you turn off automatic URL conversion, you must use the following URL address (the controller name must strictly use the name of the controller class, without 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

Where the name of the variable s can be configured

5.0 no longer supports normal URL access, so the following access is not valid, you will find no matter what you enter, Access is the default controller and operation

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

Parameter passed in

The parameters of the operation method can be implemented to automatically get the parameters of the URL, still take the above controller as an example, the controller code is as follows:


<?php
namespace app\index\controller;
class Index
{
  public function index()
  {
    return 'index';
  }
  public function hello($name = 'World')
  {
    return 'Hello,' . $name . '!';
  }
}

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, and the name parameter uses the default value of world. If the name parameter is passed in, use:

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

The results of the page output are:

hello,thinkphp!

Now add a second parameter to the Hello method:



public function hello($name = 'World', $city = '')
  {
    return 'Hello,' . $name . '! You come from ' . $city . '.';
  }

Access address is Http://tp5.com/index.php/index/index/hello/name/thinkphp/city/shanghai

The results of the page output are:

hello,thinkphp! You come from Shanghai.

As you can see, the Hello method automatically obtains the parameter value of the same name in the URL address as the parameter value of the method, and the incoming order of the parameter is not affected by the URL parameter order, for example, the following URL address output is the same as 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

You can further simplify the URL, if we have to clarify the order of the parameters represented by the variables, we change the URL parameter to get the way, the application configuration file Url_param_type parameter value modified as follows:


// get in order of parameters
'url_param_type' => 1, 

Now, the URL parameter to the value of the method is strictly in accordance with the operation of the variable definition sequence to pass the value, that is, we must use the following URL address to correctly pass in the name and city parameters to the Hello method: http://tp5.com/index.php/ Index/index/hello/thinkphp/shanghai

The results of the page output are:

hello,thinkphp! You come from Shanghai.

If you change the order of the parameters to http://tp5.com/index.php/index/index/hello/shanghai/thinkphp

The results of the page output are:

hello,shanghai! You come from thinkphp.

Obviously not the result we expected.

Again, we tried to pass the Http://tp5.com/index.php/index/index/hello/name/thinkphp/city/shanghai

Access will not get the correct results

[note] In order to bind parameters, the parameters of the operation method can only use the URL pathinfo variable, but not the GET or post variable

Hidden entrance

You can remove the ingress file index.php from the URL address, but you need to configure the Web server's rewrite rules for additional configuration.

In Apache, for example, you need to add a. htaccess file to the same sibling of the portal file (which is officially brought by default), as follows



<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>

If the phpstudy is used, the rules are as follows:


<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>

Next, you can use the following URL address to access the

Http://tp5.com/index/index/index
Http://tp5.com/index/index/hello

If you are using an Apache version that does not properly hide index.php using the above method, you can try configuring the. htaccess file using the following method:


<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>

If it is an nginx environment, you can add it in nginx.conf:


location / { // …..Omit part of the code
  if (!-e $request_filename) {
    rewrite ^(.*)$ /index.php?s=/$1 last;
    break;
  }
}

Defining routes

How can the index module in the URL address be omitted, the default URL address is a bit long, and the following is how to simplify URL access through routing.

We add some routing rules to the routing definition file (application/route.php), as follows:



Return [
   / / Add routing rules routing hello operation method to the index controller
   'hello/:name' => 'index/index/hello',
];

The routing rule indicates that all Hello-prefaced and parameter-accessible accesses are routed to the Hello action method of the index controller.

The URL before the route access address is: http://tp5.com/index/index/hello/name/thinkphp

After you define a route, you can only access the following URL address http://tp5.com/hello/thinkphp

[note] Once the routing rule is defined, the original URL address will be invalidated and become an illegal request.

But here's a little problem if we just visit Http://tp5.com/hello

An error will occur

In fact this is because the route does not match correctly, we modify the routing rule as follows:



Return [
   // route parameter name is optional
   'hello/[:name]' => 'index/hello',
];

by using [] wrapping the variables in the routing rules, it means that the variable is optional, and then the Http://tp5.com/hello can be accessed normally.

When the name parameter does not have an incoming value, the name parameter of the Hello method has a default value of world, so the output is hello,world!

In addition to the definitions in the routing configuration file, you can define the way you define routing rules dynamically, such as by adding the following method directly at the beginning of the routing configuration file (application/route.php):



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

The finished effect is the same as the usage configuration definition.

Whether routing is configured or defined by the route class method, it is uniformly placed in the routing profile application/route.php file

[note] The routing configuration does not support setting in the module configuration file

"Full Match"

The routes defined earlier are matched as long as Hello begins, and if a complete match is required, the following definitions can be used:



Return [
   // route parameter name is optional
   'hello/[:name]$' => 'index/hello',
];

When the routing rule ends with $, it indicates that the current routing rule requires a full match.

When we access the following URL address:

Http://tp5.com/hello//correct matching
http://tp5.com/hello/thinkphp//correct matching
Http://tp5.com/hello/thinkphp/val/value//Does not match

"Closure definition"

It is also supported to define routing rules for certain special scenarios by defining closures, for example:



Return [
   / / Define the closure
   'hello/[:name]' => function ($name) {
     Return 'Hello,' . $name . '!';
   },
];

Or



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

[note] The parameters of the closure function are the variables defined in the routing rules

Therefore, when accessing the following URL address: http://tp5.com/hello/thinkphp

Will output

hello,thinkphp!

"Set URL delimiter"

If you need to change the PathInfo parameter delimiter in the URL address, you only need to set it in the app configuration file (application/config.php):



/ / Set the pathinfo separator
'pathinfo_depr' => '-',

The routing rule definition does not require any changes, so we can access the following address: http://tp5.com/hello-thinkphp

"Route Parameters"

You can also constrain the request type of a routing rule or a condition such as a URL suffix, such as:


Return [
   / / Define the request type and suffix of the route
   'hello/[:name]' => ['index/hello', ['method' => 'get', 'ext' => 'html']],
];

The routing rules defined above limit the need for a GET request, and the suffix must be HTML, so the following access address:

Http://tp5.com/hello//invalid
http://tp5.com/hello.html//Effective
http://tp5.com/hello/thinkphp//invalid
http://tp5.com/hello/thinkphp.html//Effective

"Variable Rules"

Next, try some of the complex routing rule definitions to satisfy the different routing variables. Before this, first add a controller class as follows:


<?php
Namespace app\index\controller;
Class blog
{
   Public function get($id)
   {
     Return 'View id=' . $id . 'Content';
   }
   Public function read($name)
   {
     Return 'View name=' . $name . 'Content';
   }
   Public function archive($year, $month)
   {
     Return 'View' . $year . '/' . $month . 'Archived content';
   }
}

Add the following routing rules:


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

In the above routing rule, we have a rule constraint on the variable, and the variable rule is defined using a regular expression.

Let's look at a couple of URL access scenarios

Access to content with ID 5
Http://tp5.com/blog/5
Access to the contents of name thinkphp
http://tp5.com/blog/thinkphp
Access archived content for May 2015
Http://tp5.com/blog/2015/05

"Routing Grouping"

The above three routing rules are the beginning of a blog, so we can do the following simplification:


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

For this way of definition, we call it routing grouping, and routing grouping can improve the efficiency of route detection to some extent.

"Complex Routing"

Sometimes, you also need to make some special customizations to the URL, for example, if you want to support the following access address

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


We just have to change the routing definition rule a little bit:


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

For an abnormal specification such as blog-<year>-<month>, we need to use the < variable name > variable definition method instead of: variable name method.

For the sake of simplicity, we can also define variable rules uniformly, for example:


Return [
   // global variable rule definition
   '__pattern__' => [
     'name' => '\w+',
     'id' => '\d+',
     'year' => '\d{4}',
     'month' => '\d{2}',
   ],
   // routing rule definition
   'blog/:id' => 'blog/get',
   'blog/:name' => 'blog/read',
   'blog-<year>-<month>' => 'blog/archive',
];

The variable rules defined in __PATTERN__ we call global variable rules, which are defined in the routing rules we call local variable rules, and if a variable defines both global and local rules, the current local rule overrides the global rule, for example:


Return [
   // global variable rules
   '__pattern__' => [
     'name' => '\w+',
     'id' => '\d+',
     'year' => '\d{4}',
     'month' => '\d{2}',
   ],
   'blog/:id' => 'blog/get',
   / / Defined a local variable rule
   'blog/:name' => ['blog/read', ['method' => 'get'], ['name' => '\w{5,}']],
   'blog-<year>-<month>' => 'blog/archive',
];

URL generation

After defining the routing rules, the URL class can be used to easily generate the actual URL address (routing address), for the above routing rules, we can generate the URL address in the following way.


// Output blog/thinkphp
Url::build('blog/read', 'name=thinkphp');
Url::build('blog/read', ['name' => 'thinkphp']);
// Output blog/5
Url::build('blog/get', 'id=5');
Url::build('blog/get', ['id' => 5]);
// Output blog/2015/05
Url::build('blog/archive', 'year=2015&month=05');
Url::build('blog/archive', ['year' => '2015', 'month' => '05']);

[Note the first parameter of the]build method uses the full routing address in the route definition

You can also use the system-provided helper function URL to simplify



Url('blog/read', 'name=thinkphp');
// Equivalent to
Url::build('blog/read', 'name=thinkphp');

Typically output in a template file, you can use helper functions, such as:


{: URL (' blog/read ', ' name=thinkphp ')}

If our routing rules are adjusted, the generated URL address will change automatically

If you configure the Url_html_suffix parameter, the generated URL address is suffixed with the suffix, for example:


' Url_html_suffix '  = ' html ',

Then the generated URL address is similar



blog/thinkphp.html 
blog/2015/05.html

If your URL address is all routed, you can also use routing rules to define URL generation directly, for example:



url('/blog/thinkphp');
Url::build('/blog/8');
Url::build('/blog/archive/2015/05');

The first parameter of the build method must be consistent with the routing address defined by the route, and if your routing address is special, such as using a closure definition, you will need to manually specify the identity for the route, for example:



/ / Add hello route identifier
Route::rule(['hello','hello/:name'], function($name){
   Return 'Hello,'.$name;
});
// Quickly generate a URL based on the route ID
Url::build('hello', 'name=thinkphp');
// or use
Url::build('hello', ['name' => 'thinkphp']);
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.