我有这个控制器:
/**
* {@inheritdoc}
*
* @Route("entity/{domain_host}")
* @ParamConverter("entity", class="AppBundle:Entity", options={
* "repository_method" = "findOneByDomainHost",
* "mapping": {"domain_host": "domainHost"},
* "map_method_signature" = true
* })
*/
class EntityController extends Controller
{
...
}
通过这种方式,http://example.com/entity/another-example.com
之类的网址与动作相匹配,相应的another-example.com
实体会被水合并传递给控制器。
现在,这个实体也有一个ID。
我想截取http://example.com/entity/12345
之类的网址,并将其重定向到http://example.com/entity/another-example.com
。
为此,我在EntityController
中创建了另一种方法:
/**
* {@inheritdoc}
*
* @Route("entity/{domain_host}")
* @ParamConverter("store", class="AppBundle:Entity", options={
* "repository_method" = "findOneByDomainHost",
* "mapping": {"domain_host": "domainHost"},
* "map_method_signature" = true
* })
*/
class EntityController extends Controller
{
public function redirectIdToDomainAction(Request $request)
{
die(dump($request));
// Following will be the redirect logic
}
}
在routing.yml
中,在文件顶部:
entity_id_to_domain:
path: /entity/{id}
defaults: { _controller: AppBundle:Entity:redirectIdToDomain }
requirements:
id: ^[^.]*$
methods: [GET]
如果占位符不包含点,则实际调用redirectIdToDomain
操作(点是discrimen:如果占位符有点,则传递域,如果没有点,则占位符可能通过uts ID表示实体,我必须重定向。)
问题在于,当控制器类EntityController
使用@ParamConverter
时,占位符被解释为域,结果是我得到AppBundle:Entity object not found.
。
那么,只有在占位符有点的情况下才有办法应用@ParamConverter
吗?或者,我可以使用哪些其他方法使redirectToIdAction
工作而不会抛出Not found
例外?
答案 0 :(得分:1)
自定义ParamConverter可能会起作用,但如果您不想制作一个,则必须使用不同的ID和域名路由。
由于您的路由是在整个类上完成而不是在操作本身上完成,我担心您必须将重定向操作移动到另一个控制器类。
之后,您可以使用要求
有选择地匹配ID和域名/**
*@Route(
"entity/{domain_host}",
name="entity_domain",
requirements={"domain_host": "^(?=.*[\w])(?=.*[.]).+$"}
*)
*@ParamConverter(...)
*/
someActionOnDomainAction()
{
//...
}
/**
*@Route(
"entity/{id}",
name="entity_domain",
requirements={"id": "^[\d]$"}
*)
*/
redirectIdToDomainAction()
{
//...
}
或者,您可以将存储库方法findOneByDomainHost()
更改为findOneByDomainHostOrID()
,并使其与域名和数字ID匹配。
这样您就会遇到Object Not Found
错误,您可以随时获取实体的域名,并在同一个控制器操作中进行重定向。
以下是一个例子:
/**
* Class EntityController
*
* @Route("/entity/{domain_host}", name="domain_host")
* @ParamConverter("domain_host", class="AppBundle:Entity", options={
* "repository_method" = "findOneByHostOrID"
* })
*/
class EntityController extends Controller
{
/**
* @Route("/", name="show_domain_host")
* @param Entity $domain_host
*/
public function domain_hostAction(Entity $domain_host, Request $request)
{
$id = $domain_host->getId();
$host = $domain_host->getHost();
// Get the unconverted route parameter.
$parameter = $request->attributes->get('_route_params')['domain_host'];
if ($parameter == $domain_host->getId()){
// If the route parameter matches the ID,
// redirect to the same route using the domain host.
$url = $this->generateUrl('show_mail', ['mail' => $lib]);
return $this->redirect($url, 301);
}
return new Response("<html><body>$id $host</body></html>");
}
}
和存储库类:
class EntityRepository extends EntityRepository
{
public function findOneByHostOrID($domain_host)
{
if (preg_match("[\\d]",$domain_host)) {
return $this->findOneById($domain_host);
} else {
return $this->findOneByHost($domain_host);
}
}
}