Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of system routing in Symfony2

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article shares with you the content of a sample analysis of system routing in Symfony2. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

The details are as follows:

Beautiful URL is definitely a must for a serious web application, which allows ugly URL like index.php?article_id=57 to be hidden and replaced by more popular ones like / read/intro-to-symfony.

Flexibility is more important. What if you want to change the URL of a page, for example, from / blog to / new?

How many links do you need to find and update? If you use Symfony's router, this change will become very simple.

Symfony2 router allows you to define a more creative URL, and you can map different areas of your application.

Create complex routes and map to controllers and generate URLs within templates and controllers

Load routing resources from bundles (or anywhere else)

Debug your routing

Routing activity

A path is a binding from URL mode to a controller.

For example, suppose you want to match any paths like / blog/my-post or / blog/all-about-symfony and send them to a controller where you can find and render blog entities.

The path is simple:

YAML format:

# app/config/routing.ymlblog_show:pattern: / blog/ {slug} defaults: {_ controller: AcmeBlogBundle:Blog:show}

XML format:

AcmeBlogBundle:Blog:show

PHP code format:

/ / app/config/routing.phpuse Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog_show', new Route (' / blog/ {slug}', array ('_ controller' = > 'AcmeBlogBundle:Blog:show',)

The blog_show path defines a URL pattern that looks like / blog/* where the wildcard character is named slug. For the URL/blog/my-blog-post,slug variable, you get the value my-blog-post.

The _ controller parameter is a specific key that tells Symfogy which controller will be executed when a URL matches the path.

The _ controller string is called a logical name. Its values specify specific PHP classes and methods according to a specific pattern.

/ / src/Acme/BlogBundle/Controller/BlogController.phpnamespace Acme\ BlogBundle\ Controller;use Symfony\ Bundle\ FrameworkBundle\ Controller\ Controller;class BlogController extends Controller {public function showAction ($slug) {$blog = / / use the $slug variable to query the database return $this- > render ('AcmeBlogBundle:Blog:show.html.twig', array (' blog' = > $blog,));}}

Now when you visit / blog/my-post again, showAction controller will be executed and the value of the $slug variable will be my-post

The router goal of Symfogy2: map a requested URL to controller.

Routing: internal secrets

When a request is sent to an application, it contains an address where the client wants to get the resource. This address is called URL or URI. It could be / contact,/blog/read-me or some other style.

GET / blog/my-blog-post

The goal of the Symfony2 routing system is to parse these URL and decide which controller should be executed to reply to the request.

The whole routing process can be divided into:

1. The request is processed by the front-end controller (app.php) of the Symfony2.

The 2.Symfony2 core (kernel) requires the router to check the request.

3. The router matches the received URL to a specific path and returns information about it, including the controller that should be executed.

The 4.Symfony2 core executes the controller, and the controller eventually returns a Response object.

The router layer is a tool that converts the received URL into a specific controller to be executed.

Create a rout

Symfony will load all routes for your application from a single routing configuration file. This file is usually app/config/routing.yml. It can be configured to include files such as XML or PHP files.

YAML format:

# app/config/config.ymlframework: #... Router: {resource: "% kernel.root_dir%/config/routing.yml"}

XML format:

PHP code format:

/ / app/config/config.php$container- > loadFromExtension ('framework', array (/ /... 'router' = > array (' resource' = >'% kernel.root_dir%/config/routing.php'),)

Basic routing configuration

Defining a route is simple, and an application usually has many routes. A basic route consists of two parts: the pattern part and the defaults array part.

For example:

YAML format:

_ welcome: pattern: / defaults: {_ controller: AcmeDemoBundle:Main:homepage}

XML format:

AcmeDemoBundle:Main:homepage

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('_ welcome', new Route ('/', array ('_ controller' = > 'AcmeDemoBundle:Main:homepage',); return $collection

The route matches the home page (/) and maps to AcmeDemoBundle:Main:homepage controller. The _ controller string is translated by Symfony2 into a corresponding PHP function and executed.

Placeholder routing

Of course, the routing system supports more interesting routes. Many routes contain one or more named wildcard placeholders.

YAML format:

Blog_show: pattern: / blog/ {slug} defaults: {_ controller: AcmeBlogBundle:Blog:show}

XML format:

AcmeBlogBundle:Blog:show

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog_show', new Route (' / blog/ {slug}', array ('_ controller' = > 'AcmeBlogBundle:Blog:show',)); return $collection

This pattern will match any URL in the form of / blog/*. The value of the matching placeholder {slug} will be used in controller. In other words, if URL is / blog/hello-world, the value of the $slug variable is hello-world, which can be used in controller. This pattern does not match things like / blog, because all placeholders are required by default. Of course, you can change it by assigning these placeholders in the defaults array.

Required and optional placeholder

Let's add a new route that displays a list of all available blog.

YAML format:

Blog: pattern: / blog defaults: {_ controller: AcmeBlogBundle:Blog:index}

XML format:

AcmeBlogBundle:Blog:index

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog', new Route (' / blog', array ('_ controller' = > 'AcmeBlogBundle:Blog:index',); return $collection

So far, our routes have been very simple route patterns. The non-placeholders they contain will be exactly matched.

If you want the route to support paging, such as letting / blog/2 display the blog on the second page, you need to add a new {page} placeholder for the previous route.

YAML format:

Blog: pattern: / blog/ {page} defaults: {_ controller: AcmeBlogBundle:Blog:index}

XML format:

AcmeBlogBundle:Blog:index

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog', new Route (' / blog/ {page}', array ('_ controller' = > 'AcmeBlogBundle:Blog:index',)); return $collection

Like the previous {slug} placeholder, the {page} placeholder will be available inside your controller, and its value can be used to represent the page number of the blog value to be displayed. But be clear, because placeholders are required by default, the route will no longer match the previous / blog URL, so if you still want to see the first page, you will have to access it through / blog/1 URL. To resolve this problem, specify the default value of {page} in the defaults array of the route.

YAML format:

Blog: pattern: / blog/ {page} defaults: {_ controller: AcmeBlogBundle:Blog:index, page: 1}

XML format:

AcmeBlogBundle:Blog:index 1

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog', new Route (' / blog/ {page}', array ('_ controller' = > 'AcmeBlogBundle:Blog:index',' page' = > 1,)); return $collection

By adding page to the defaults key, the {page} placeholder is no longer required. At this point / blog will be matched and the page parameter will be set to 1MagneURL / blog/2 will also be matched.

Add a requirement constraint

Take a look at these routes:

YAML format:

Blog: pattern: / blog/ {page} defaults: {_ controller: AcmeBlogBundle:Blog:index, page: 1} blog_show: pattern: / blog/ {slug} defaults: {_ controller: AcmeBlogBundle:Blog:show}

XML format:

AcmeBlogBundle:Blog:index 1 AcmeBlogBundle:Blog:show

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog', new Route (' / blog/ {page}', array ('_ controller' = > 'AcmeBlogBundle:Blog:index',' page' = > 1,)); $collection- > add ('blog_show', new Route (' / blog/ {show}', array ('_ controller' = > 'AcmeBlogBundle:Blog:show',); return $collection

Did you find the problem? Notice that both routes match URL of type / blog/*. Symfony will only choose the first route that matches it.

In other words, blog_show will never be matched by a URL of type / blog/*. URL like / blog/my-blog-post will also be matched by blog routes, and the page variable will get a value like my-blog-post.

This is definitely not possible, so what should we do? The answer is to add a constraint to the route that requires requirements.

In blog routes, the placeholder {page} ideally matches only integer values. Fortunately, regular expression can easily meet this requirement.

YAML format:

Blog: pattern: / blog/ {page} defaults: {_ controller: AcmeBlogBundle:Blog:index, page: 1} requirements: page:\ d +

XML format:

AcmeBlogBundle:Blog:index 1\ d +

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('blog', new Route (' / blog/ {page}', array ('_ controller' = > 'AcmeBlogBundle:Blog:index',' page' = > 1,), array ('page' = >'\ dcards,)); return $collection

Here the\ d + constraint is a regular expression that specifies that {page} accepts only integers. In this way, things like / blog/my-blog-post are no longer matched. At this point, it will be matched by the blog_show route. Because the constraints of the parameters are regular expressions, it is up to you to determine the complexity and flexibility.

Assuming that the home page uses two languages, routing can be configured as follows:

YAML format:

Homepage: pattern: / {culture} defaults: {_ controller: AcmeDemoBundle:Main:homepage, culture: en} requirements: culture: en | fr

XML format:

AcmeDemoBundle:Main:homepage en en | fr

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('homepage', new Route (' / {culture}', array ('_ controller' = > 'AcmeDemoBundle:Main:homepage',' culture' = > 'en',), array (' culture' = >'en | fr',); return $collection

Add HTTP method constraint

In addition to URL, you can also match the requested method (GET,HEAD,POST,PUT,DELETE, etc.). Suppose you have a contact form with two controller, one for displaying the form (using GET requests) and one for processing submitted forms (POST requests). It is configured as follows:

YAML format:

Contact: pattern: / contact defaults: {_ controller: AcmeDemoBundle:Main:contact} requirements: _ method: GETcontact_process: pattern: / contact defaults: {_ controller: AcmeDemoBundle:Main:contactProcess} requirements: _ method: POST

XML format:

AcmeDemoBundle:Main:contact GET AcmeDemoBundle:Main:contactProcess POST

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('contact', new Route (' / contact', array ('_ controller' = > 'AcmeDemoBundle:Main:contact',), array (' _ method' = > 'GET',); $collection- > add (' contact_process', new Route ('/ contact', array ('_ controller' = > 'AcmeDemoBundle:Main:contactProcess',), array (' _ method' = > 'POST',)); return $collection)

Although the two routes have the same URL pattern definition (/ contact), the first route only matches the GET request, while the second route matches only the POST request. This means that you can display and submit forms through the same URL and process them with different controller. If no _ method constraint is specified, the route matches all request methods. Like other constraints, the _ method constraint accepts regular expressions. If you only want to match GET or POST, you can use GET | POST

Examples of advanced routing:

Symfony2 has everything you need to create any form of routing.

YAML format:

Article_show: pattern: / articles/ {culture} / {year} / {title}. {_ format} defaults: {_ controller: AcmeDemoBundle:Article:show, _ format: html} requirements: culture: en | fr _ format: html | rss year:\ d +

XML format:

AcmeDemoBundle:Article:show html en | fr html | rss\ d +

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('homepage', new Route (' / articles/ {culture} / {year} / {title}. {_ format}', array ('_ controller' = > 'AcmeDemoBundle:Article:show',' _ format' = > 'html',), array (' culture' = >'en | fr','_ format' = > html | rss', 'year' = >'\ dwells,)); return $collection

The above route, when matching, only matches the {culture} part of the URL whose value is en or fr and the value of {year} is numeric. The route also tells us that intervals can be used instead of slashes between placeholders.

It can match the following URL:

/ articles/en/2010/my-post

/ articles/fr/2010/my-post.rss

There is a special routing parameter, _ format, whose value changes to the request format when used. This request format is equivalent to the Content-Type of the Respose object, for example, the json request format is translated into a Content-Type to application/json. This parameter can be used to render a different template for each _ format in controller. It is a powerful way to render the same content to different formats.

Special routing parameters:

As you can see, each routing parameter or default value is ultimately used as an input parameter for the controller method. In addition, there are three special parameters, each of which adds a unique function to your application.

_ controller: this parameter determines which controller is executed when the route matches.

_ format: used to format the request.

_ locale: used to set localization on session.

The naming mode of Controller:

Each route must have a _ controller parameter that determines which controller should be executed when the route matches. This parameter uses a single string pattern, which is called logical controller name.

Through it Symfony can be mapped to a specific PHP method and class. The mode has three parts, each separated by a colon:

Bundle:controller:action

For example, the value of _ controller is AcmeBlogBundle:Blog:show, which means the showAction method in the BlogController class in AcmeBlogBundle bundle.

/ / src/Acme/BlogBundle/Controller/BlogController.phpnamespace Acme\ BlogBundle\ Controller;use Symfony\ Bundle\ FrameworkBundle\ Controller\ Controller;class BlogController extends Controller {public function showAction ($slug) {/ /...}}

Symfony will automatically add their suffixes, Blog= > BlogController, show = > showAction.

You can also use its fully qualified name and method to assign a value to _ controller, Acme\ BlogBundle\ Controller\ BlogController::showAction, but generally use logical names for simplicity and flexibility. In addition to the above two forms, Symfony also supports the third way to have only a colon separator, such as service_name:indexAction to assign a controller to _ controller as a service.

Routing parameters and controller parameters

Routing parameters are important because each routing parameter is transformed into a controller parameter that is used in the method.

Public function showAction ($slug) {/ /...}

In fact, the parameter values of all the defaults collections and forms are merged into a single array. Each key in this array becomes a parameter to the controller method. In other words, for each parameter of your controller method, Symfony looks from the routing parameters and assigns the value found to the parameter. The variables $culture and $year,$title,$_format,$_controller in the above example are used as arguments to the showAction () method. Because the placeholder and the defaults collection are merged, even the $_ controller variable is the same. You can also use a special variable $_ route to specify the name of the route.

Include external routing resourc

All routing resources are imported through a single configuration file. Usually app/config/routing.yml. Of course, you may want to import routing resources from elsewhere, such as the routing resources in your defined bundle. You can import them like this:

YAML format:

# app/config/routing.ymlacme_hello: resource: "@ AcmeHelloBundle/Resources/config/routing.yml"

XML format:

PHP code format:

/ / app/config/routing.phpuse Symfony\ Component\ Routing\ RouteCollection;$collection = new RouteCollection (); $collection- > addCollection ($loader- > import ("@ AcmeHelloBundle/Resources/config/routing.php")); return $collection

Keys, such as acme_hello, are meaningless when using YAML to import a resource, only to ensure that the resource is uniquely not overwritten by other lines. Use resources key to load the given routing resource. In this example, the resource is a full-path file, and @ AcmeHelloBundle is the abbreviated syntax, which is pointed to the bundle path. The contents of the imported file are as follows:

YAML format:

# src/Acme/HelloBundle/Resources/config/routing.ymlacme_hello: pattern: / hello/ {name} defaults: {_ controller: AcmeHelloBundle:Hello:index}

XML format:

AcmeHelloBundle:Hello:index

PHP code format:

/ / src/Acme/HelloBundle/Resources/config/routing.phpuse Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('acme_hello', new Route (' / hello/ {name}', array ('_ controller' = > 'AcmeHelloBundle:Hello:index',)); return $collection

The routes in this file are parsed and loaded along with the main routing file contents.

Add prefixes to imported routing resources

You can choose a prefix for the imported routing resource, for example, suppose you want a matching pattern for acme_hello routes: / admin/hello/ {name} instead of direct / hello/ {name}

Then you can specify prefix for it when you import it.

YAML format:

# app/config/routing.ymlacme_hello: resource: "@ AcmeHelloBundle/Resources/config/routing.yml" prefix: / admin

XML format:

PHP code format:

/ / app/config/routing.phpuse Symfony\ Component\ Routing\ RouteCollection;$collection = new RouteCollection (); $collection- > addCollection ($loader- > import ("@ AcmeHelloBundle/Resources/config/routing.php"),'/ admin'); return $collection

The string / admin is inserted in front of the matching pattern when the external routing resource is loaded.

Visualize and debug routin

When you add and personalize routes, it is very useful to be able to see it and get some details. A good way to view your application's routes is through the router:debug command line tool.

Execute the following command in your project directory:

$php app/console router:debug

All routes for your application will be output. You can also add the name of a route to the command to get a single route information

$php app/console router:debug article_show

Generate URL

A routing system should also be able to generate URL. In fact, the routing system is a two-way system, mapping URL to controller+parameters and back to a URL. You can use the match () and generate () methods to do this. For example:

$params = $router- > match ('/ blog/my-blog-post'); / / array ('slug' = >' my-blog-post','_ controller' = > 'AcmeBlogBundle:Blog:show') $uri = $router- > generate (' blog_show', array ('slug' = >' my-blog-post')); / / blog/my-blog-post

To generate a URL, you need to specify the name of the route (such as blog_show) and any wildcard (such as: slug=my-blog-post) as parameters. With this information, arbitrary URL can be generated.

Class MainController extends Controller {public function showAction ($slug) {/ /... $url = $this- > get ('router')-> generate (' blog_show', array ('slug' = >' my-blog-post'));}}

So how do you generate URL from within the template? If your application front end uses AJAX requests, you may want to be able to generate URL in javascript based on your routing configuration by using the

FOSJsRoutingBundle (https://github.com/FriendsOfSymfony/FOSJsRoutingBundle) you can do this:

Var url = Routing.generate ('blog_show', {"slug":' my-blog-post'})

Generate URL for absolute path

By default, the router generates the URL of the relative path (such as / blog). To generate an absolute path URL, simply pass a true to the generate method as the third parameter value.

$router- > generate ('blog_show', array (' slug' = > 'my-blog-post'), true); / / http://www.example.com/blog/my-blog-post

When generating an absolute path URL, the host is the host of the current request object, which is automatically determined based on the server information provided by the PHP. When you need to generate an absolute URL for a script running a subcommand line, you need to manually set the desired host header on the Request object.

$request- > headers- > set ('HOST',' www.example.com')

Generate URL with query string

Generate () takes an array wildcard value to generate URI. But if you pass in an extra value, it will be added to URI as the query string:

$router- > generate ('blog', array (' page' = > 2, 'category' = >' Symfony')); / / blog/2?category=Symfony

Generate URL from a template

The most common place to generate URL is when linking two pages from a template, which requires the use of a template helper function:

Twig format:

Read this blog post.

PHP format:

AcmeDemoBundle:Main:secure https

PHP code format:

Use Symfony\ Component\ Routing\ RouteCollection;use Symfony\ Component\ Routing\ Route;$collection = new RouteCollection (); $collection- > add ('secure', new Route (' / secure', array ('_ controller' = > 'AcmeDemoBundle:Main:secure',), array (' _ scheme' = > 'https',); return $collection

The routing definition above is to force secure routes to be accessed using the HTTPS protocol.

On the contrary, when the URL of secure is generated, the routing system will generate the corresponding access protocol according to the current access protocol scheme. For example, if it is currently HTTP, HTTPS access will be generated automatically; if it is HTTPS access, HTTPS access will be generated accordingly.

# if the scheme is HTTPS {{path ('secure')}} # generate / secure# if the scheme is HTTP {{path (' secure')}} # generate https://example.com/secure

Of course, you can also force the use of HTTP access protocol by setting _ scheme to HTTP. In addition to the above-mentioned setting method of forcing access using the HTTPS protocol, there is also a method for site locale

Using requires_channel for example, you want all routes in your site / admin to be accessed using the HTTPS protocol, or your secure route definition is used in a third-party bundle.

Thank you for reading! This is the end of this article on "sample Analysis of system routing in Symfony2". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report