为什么这个Symfony2路由不起作用?

I have a problem with the routing in Symfony2.

Actually I downloaded the latest release and run it on my server. The demo works fine.

Now I want to do the following: I want to create a TestController, this controller should have:

  • an index view
  • a view like hello world
  • a view where i can pass 2 parameters

So I started to create a new controller in the src\Acme\DemoBundle\Controller folder called TestController. Here is the code:

<?php

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Acme\DemoBundle\Form\ContactType;

// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class TestController extends Controller
{
    public function indexAction()
    {
        return array();
    }

    public function hello2Action($name1, $name2)
    {
        return array();
    }

    public function helloAction()
    {
        return array();
    }
}

Then I created 3 views in a new folder src\Acme\DemoBundle\Resources\views\Test called hello.html.twig, index.html.twig and hello2.html.twig

Both of them have a content like this

{% extends "AcmeDemoBundle::layout.html.twig" %}

{% block title "Symfony - Demos" %}

{% block content_header '' %}

{% block content %}
    foo!!!
{% endblock %}

Finally I edited the routing.dev.yml and added somthing like this:

_name1:
    resource: "@AcmeDemoBundle/Controller/TestController.php"
    type:     annotation
    prefix:   /test

_name2:
    resource: "@AcmeDemoBundle/Controller/TestController.php"
    type:     annotation
    prefix:   /test/hello

_name3:
    resource: "@AcmeDemoBundle/Controller/TestController.php"
    type:     annotation
    prefix:   /test/hello2/{name1}&{name2}

When i want to run the test controller i get:

No route found for "GET /test/"

What is wrong? Is it possible to have one view for two controller functions? (like hello() and hello($foo))?

You can also do this:

  1. In routing_dev.yml, make sure you have this:

     _main:
         resource: routing.yml
    
  2. In routing.yml, add something like this:

       AcmeDemoBundle:
          resource: "@AcmeDemoBundle/Resources/config/routing.yml"
          prefix:   /test
    

    You can select the prefix you want in accessing that particular bundle.

  3. In Acme/DemoBundle/Resources/config/routing.yml you can now add your route patterns.

      name1:
          pattern: /
          defaults: { _controller: AcmeDemoBundle:Test:index }
    
      name2:
          pattern: /hello
          defaults: { _controller: AcmeDemoBundle:Test:hello }
    
      name3:
          pattern: /hello2/{name1}/{name2}
          defaults: { _controller: AcmeDemoBundle:Test:hello2 }
    

And you can now access, route /test, /test/hello and /test/hello2/firstname/lastname'. This is just one way of managing routes in symfony 2. This might help: http://symfony.com/doc/current/book/routing.html

In your routing you defined prefixes, but not actually the routes. Since you are using annotations - routes must be defined via annotations in the Controller.

See this great manual ;)

Your routing_dev.yml should look like this:

_name1:
    resource: "@AcmeDemoBundle/Controller/TestController.php"
    type:     annotation

And in your controller you should define @Route for each action:

/**
 * @Route("/hello")
 */
public function helloAction()
{
    return array();
}

After this you'll be able to access your action by route /hello and so on.

Cheers ;)

Two things:

  • You have defined a route for "/test" but not for "/test/", that is why you got your first error message (No route found for "GET /test/"). In any case, it is better to define routes as annotations as suggested in another answer.

  • In order for Controllers to work with the structure you are using (returning and array of variables, in this case an empty array), you need to mark them with the "@Template" annotation like so:

/*

* @Route("/hello/{name}", name="_demo_hello")
* @Template()
*/    
public function helloAction($name)

This makes Symfony look automatically for the corresponding template files. If you don´t do this, you need to return a Response object, indicating the template that should be rendered, something like this:

return $this->render('AcmeDemoBundle:Test:index.html.twig');