Symfony:路由覆盖其他模板
Symfony : Route overrides other templates
问题出在路由 @Route("/{cityId}")
的奇怪行为中。当此路由高于其他路由时(例如 @Route("/editcity_{id}")
),它会覆盖模板。
看截图:
- 路线
/{cityId}
是第一个,/editcity_{id}
是最后一个。
当我尝试转到 /editcity_2
路由时 /2
处理请求并且 city.html.twig
显示此错误:
- 2.when
/editcity_{id}
是第一条路线,/{cityId}
是第二条路线,一切正常。
这是我的:
CityController.php
:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\City;
use AppBundle\Form\Type\CityType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class CityController extends Controller
{
/**
* @Route("/addcity")
* @param Request $request
* @return Response
*/
public function addCityAction(Request $request) {
$city = new City();
$form = $this->createForm(CityType::class, $city);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($city);
$em->flush();
return new Response('Created city id '.$city->getId());
}
return $this->render(':appviews:addCity.html.twig', array(
'form' => $form->createView(),
));
}
/**
* @Route("/cities")
*/
public function citiesAction(){
$em = $this->getDoctrine()->getEntityManager();
$cities = $em->getRepository('AppBundle:City')->findAll();
return $this->render('appviews/citiesList.html.twig',array('cities'=>$cities));
}
/**
* @Route("/{cityId}")
*/
public function cityAction($cityId) {
$em = $this->getDoctrine()->getManager();
$city = $em->getRepository('AppBundle:City')->find($cityId);
return $this->render('appviews/city.html.twig',array(
'city' => $city));
}
/**
* @Route("/editcity_{id}")
* @return Response
*/
public function editCityAction($id, Request $request) {
$em = $this->getDoctrine()->getEntityManager();
$city = $em->getRepository('AppBundle:City')->find($id);
$form = $this->createForm(CityType::class, $city);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($city);
$em->flush();
return new Response('Created city id '.$city->getId());
}
return $this->render(':appviews:editCity.html.twig', array(
'form' => $form->createView(),
));
}
Twig 模板,city.html.twig
{% extends "appviews/base.html.twig" %}
{% block title %}Cтраница города {% endblock %}
{% block body %}
{{ dump(city)}}
{{ city.link }}
{% endblock %}
你得到的是正常行为,因为
the Symfony router will always choose the first matching route it finds
并且您的 /{cityId}
路线等同于 /*
这对于这些 URL 是正确的,例如:
/123
/add-new-article
/edit-123
/article-123.html
/123-article.html
因此您的 /editcity_{id}
路线将永远不会匹配,因为这是您的 /{cityId}
路线的情况。但是您可以通过添加路线要求或路线条件来避免这种情况:
/**
* @Route("/{cityId}", requirements={ "cityId": "\d+" })
*/
The \d+
requirement is a regular expression that says that the value of the {cityId}
parameter must be a digit (i.e. a number).
之后,像 /editcity_123
这样的 URL 将永远不会匹配 /{cityId}
路由,而只会匹配 /editcity_{id}
路由。
所以不要忘记在您的路线中添加要求以获得清晰的代码并避免此类问题,当然是在您需要的时候。
参考文献。 :
http://symfony.com/doc/current/book/routing.html#adding-requirements
希望能帮到你。
问题出在路由 @Route("/{cityId}")
的奇怪行为中。当此路由高于其他路由时(例如 @Route("/editcity_{id}")
),它会覆盖模板。
看截图:
- 路线
/{cityId}
是第一个,/editcity_{id}
是最后一个。
- 路线
当我尝试转到 /editcity_2
路由时 /2
处理请求并且 city.html.twig
显示此错误:
- 2.when
/editcity_{id}
是第一条路线,/{cityId}
是第二条路线,一切正常。
这是我的:
CityController.php
:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\City;
use AppBundle\Form\Type\CityType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class CityController extends Controller
{
/**
* @Route("/addcity")
* @param Request $request
* @return Response
*/
public function addCityAction(Request $request) {
$city = new City();
$form = $this->createForm(CityType::class, $city);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($city);
$em->flush();
return new Response('Created city id '.$city->getId());
}
return $this->render(':appviews:addCity.html.twig', array(
'form' => $form->createView(),
));
}
/**
* @Route("/cities")
*/
public function citiesAction(){
$em = $this->getDoctrine()->getEntityManager();
$cities = $em->getRepository('AppBundle:City')->findAll();
return $this->render('appviews/citiesList.html.twig',array('cities'=>$cities));
}
/**
* @Route("/{cityId}")
*/
public function cityAction($cityId) {
$em = $this->getDoctrine()->getManager();
$city = $em->getRepository('AppBundle:City')->find($cityId);
return $this->render('appviews/city.html.twig',array(
'city' => $city));
}
/**
* @Route("/editcity_{id}")
* @return Response
*/
public function editCityAction($id, Request $request) {
$em = $this->getDoctrine()->getEntityManager();
$city = $em->getRepository('AppBundle:City')->find($id);
$form = $this->createForm(CityType::class, $city);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($city);
$em->flush();
return new Response('Created city id '.$city->getId());
}
return $this->render(':appviews:editCity.html.twig', array(
'form' => $form->createView(),
));
}
Twig 模板,city.html.twig
{% extends "appviews/base.html.twig" %}
{% block title %}Cтраница города {% endblock %}
{% block body %}
{{ dump(city)}}
{{ city.link }}
{% endblock %}
你得到的是正常行为,因为
the Symfony router will always choose the first matching route it finds
并且您的 /{cityId}
路线等同于 /*
这对于这些 URL 是正确的,例如:
/123
/add-new-article
/edit-123
/article-123.html
/123-article.html
因此您的 /editcity_{id}
路线将永远不会匹配,因为这是您的 /{cityId}
路线的情况。但是您可以通过添加路线要求或路线条件来避免这种情况:
/**
* @Route("/{cityId}", requirements={ "cityId": "\d+" })
*/
The
\d+
requirement is a regular expression that says that the value of the{cityId}
parameter must be a digit (i.e. a number).
之后,像 /editcity_123
这样的 URL 将永远不会匹配 /{cityId}
路由,而只会匹配 /editcity_{id}
路由。
所以不要忘记在您的路线中添加要求以获得清晰的代码并避免此类问题,当然是在您需要的时候。
参考文献。 : http://symfony.com/doc/current/book/routing.html#adding-requirements
希望能帮到你。