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. Follow the small series together to see it, hope to help everyone.
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:
<?phpnamespace 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):
<?phpnamespace 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 URL Auto-conversion (Support hump access Controller) ' Url_convert ' and 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:
<?phpnamespace 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 the ' url_param_type ' = 1 in order of the parameters,
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-multiviewsrewriteengine onRewriteCond%{REQUEST_FILENAME}!- Drewritecond%{request_filename}!-frewriterule ^ (. *) $ 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-multiviewsrewriteengine onRewriteCond%{REQUEST_FILENAME}!- Drewritecond%{request_filename}!-frewriterule ^ (. *) $ 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 Route rule routed to index controller's Hello action method ' 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 [ //routing 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 [ //routing 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 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 delimiter ' 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 route request type and suffix ' 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:
<?phpnamespace app\index\controller;class blog{public function Get ($id) { return ' view id= '. $id. ' The content '; } Public function read ($name) { return ' view Name= '. $name. ' The 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} ', ' Mo Nth ' + ' \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 Rule ' __pattern__ ' = [' name ' = ' = ' \w+ ', ' id ' = ' \d+ ' , ' year ' = > ' \d{4} ', ' month ' = ' \d{2} ', ], ' blog/:id ' = ' blog/get ', //define local variable rules ' 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/thinkphpurl::build (' Blog/read ', ' name=thinkphp '); Url::build (' Blog/read ', [' name ' = ' thinkphp ']);//Output Blog/5url::build (' Blog/get ', ' id=5 '); Url::build (' Blog/get ', [' id ' = 5]);//Output Blog/2015/05url::build (' blog/archive ', ' year=2015&month=05 '); Url::build (' blog/archive ', [' Year ' = ' + ', ' 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 the Hello route identity route::rule ([' Hello ', ' hello/:name '], function ($name) { return ' Hello, '. $name;}); /Fast generation of Urlurl::build (' Hello ', ' name=thinkphp ') based on route identification;//or using Url::build (' Hello ', [' name ' = ' thinkphp ']);