使用 Symfony 路由从 .htaccess 重写 URL
Posted
技术标签:
【中文标题】使用 Symfony 路由从 .htaccess 重写 URL【英文标题】:URL Rewriting from .htaccess with Symfony Routing 【发布时间】:2018-03-15 12:56:48 【问题描述】:我在使用 Symfony (2.8) 重写 URL 时遇到了一些麻烦 我的目标是重定向一些 URL 而不让它们在浏览器栏中更改。
我需要这个,以便 URL 可以具有自定义的、人类可读的形式,并且可以共享。
URL 也用于表单,因此数据以?param=data
形状发送
Homewever,Symfony 内部路由似乎不太适合它(或者我可能忽略了一些东西,但我整天都在寻找这个问题,但没有找到正确的答案)
没有框架,在 .htaccess 如果用户去
www.website.com/search/London/15
我会将它们重定向到
www.website.com/searchEngine?search_action[city]=London&search_action[radius]=15
无需更改浏览器 URL,因此 searchEngine 永远不会出现,只需一个简单的 RewriteRule
RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [L]
但是一旦我尝试对 Symfony 使用相同的规则(在 /web 文件夹中的 .htaccess 中,对吗?),
www.website.com/search/London/15 登陆 Symfony 404 错误页面
我的猜测是 Symfony 试图寻找一个内部 /Search 路由,该路由不存在,因为该 URL 旨在通过 .htaccess 静默重定向到 SearchEngin
搜索引擎路由确实存在并且www.website.com/SearchEngine?search_action[city]=London&search_action[radius]=15
工作得很好
到目前为止,如果我将 R 标志添加到 RewriteRule,.htaccess 和 Symfony 可以一起工作
RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [R,L]
但这是因为 URL 在被重定向到 SearchEngine 时在浏览器中发生了变化。
有没有办法让 Symfony 知道 /search/London/15
导致 SearchEngine?search_action[city]=London&search_action[radius]=15
,并且在不改变 Url 的情况下工作?
有人知道我应该为此调整什么吗?
路由
非常基本,一个单独的路由仅用于该 URL 可读功能和搜索,没有什么太花哨的。
routing.yml
research_action:
path: /SearchEngine
defaults: _controller: "MySearchBundle:Search:search"
SearchController:searchAction
public function searchAction(Request $request)
/*
expect search_action[city]=London and search_action[radius]=15
*/
$form = $this->createForm('MySearchBundle\Form\Type\SearchType',null);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
//Get here without problem when from SearchEngine?search_action[city]=London&search_action[radius]=15
/*
This is where Zhuli do the thing
*/
return $this->render('SomeDefaultPage.html.twig');
.htaccess
...
//Basic Symfony Routing stuff
RewriteCond %REQUEST_FILENAME -f
RewriteRule .? - [L]
#Doesn't work without that R tag
RewriteRule search/(.*)/(.*)$ /SearchEngine?search_action[city]=$1&search_action[radius]=$2 [R=301,L]
# Rewrite all other queries to the front controller.
RewriteRule .? %ENV:BASE/app.php [L]
.....
【问题讨论】:
显示你的 Symfony 路由配置,可能还有你的控制器。这将使您更容易看到哪里出错了。您可以为单个控制器操作配置多个路由,所以也许这会有所帮助.. 已添加,抱歉花了一些时间 @naththedeveloper 我看到了这个想法,但是为了让表单在它后面工作,Symfony 需要接收/SearchEngine?search_action[city]=Prague&search_action[radius]=15
并且除非我决定调整表单处理请求的方式,否则我不认为添加多条路线可以工作。
你有没有试过把你的自定义规则放在 htaccess 中的 symfony 规则之前?这应该可以阻止它干扰......
@Bananaapple ?我没试过,但是 Symfony 规则会干扰什么?
【参考方案1】:
所以我发现了一些东西
这比 .htaccess
中的规则要长得多,但我找不到其他解决方法。
我创建了一个新路由,它将转发 /search/London/15
查询到搜索引擎
forward_action:
path: /search/city/radius
defaults: _controller: "MySearchBundle:Search:searchForward"
控制器
在控制器操作中,我检索传递给 Request:ParameterBag 的 URL 属性(城市和半径);然后我将其转发给 SearchEngineAction
public function searchForwardAction(Request $request,$city,$radius)
//Putting the attribute in an array
$query['city']=$city;
$query['radius']=$radius;
/*
Which I pass to the request as a parameter
The forward will treat this like a Get Query
?search_action[city]=$city&search_action[radius]=$radius
*/
$request->query->set('search_action',$query);
//Forwarding !
return $this->forward('MySearchBundle:Search:search', array('request' => $request));
因为我使用forward()
,所以浏览器上的 URL 就像 /Search/Kyoto/25
但返回/SearchEngine?search_action[city]=Kyoto&search_action[radius]=25
的结果
它工作得很好,但是如果将它与 .htaccess 中的正常 single 规则进行比较(仍然无法正常工作),那么仅此 URL 重写的代码量和工作量就会变得相当繁重
我将不得不修改搜索表单指向的位置
我怀疑它是否是最好的解决方案,因为对于这样一个简单的任务来说它是相当复杂的。
有谁好转了吗?
【讨论】:
以上是关于使用 Symfony 路由从 .htaccess 重写 URL的主要内容,如果未能解决你的问题,请参考以下文章
apache_conf 修改后的Symfony2 .htaccess文件,可以从Apache虚拟主机设置前端控制器(有点像Rails)。