我在用:
- Symfony v3.0.6;
- 教义 v2.5.4
我在学说查询中使用 LIKE 建立了站点搜索。
// My search query
$query = $em->createQueryBuilder()
->select('i')
->from('AppBundle:Item', 'i')
->where('i.name_lv LIKE :term')
->andWhere('i.description_lv LIKE :term')
->setParameter('term', '%' . $term . '%')
->orderBy('i.price', 'DESC')
->getQuery();
如果我手动将请求写入浏览器地址栏,它工作正常。
例如:
返回包含已搜索产品的页面。
问题:
虽然当我在表单中使用搜索按钮时(就像每个用户都应该)
// Relevant part of twig template showing my search form
<div class="search-box row clearfix text-center">
<form id="search-form" method="GET">
<fieldset>
<p>{{ "goods.msg.searchSomething"|trans }}</p>
<input type="text" class="input-term" name="term" />
<p>{{ msg }}</p>
<input type="submit" class="input-submit button small success" value="{{ "goods.button.search"|trans }}" />
</fieldset>
</form>
</div>
我的路径有问题 - 因为
然后我得到如下丑陋的 URL:
- http://localhost:8000/lv/search?term=productName
- http://localhost:8000/lv/search/productName?term=orherProductName
我怀疑,这可能是URL 重写或路由问题
我总是需要漂亮的 URL - 不仅在手动输入 URL 时,而且在使用表单搜索产品时。
以下是搜索控制器的相关代码:
// start of function: searchAction
// getting GET parameter
$term = $request->get('term');
// end of function: searchAction
// rendering template with additional parameters
return $this->render('search/search.html.twig', array(
'search_items' => $search_items,
'msg' => '',
'term' => $term
));
这是我的路由:
goods_search_show:
path: /{_locale}/search-show/{id}/{term}
defaults: { _controller: 'AppBundle:Search:searchShow', id: 1, term: '' }
requirements:
_locale: lv|en|ru
id: \d+
goods_search_no_term:
path: /{_locale}/search
defaults: { _controller: 'AppBundle:Search:search' }
requirements:
_locale: lv|en|ru
goods_search:
path: /{_locale}/search/{term}
defaults: { _controller: 'AppBundle:Search:search', term: '' }
requirements:
_locale: lv|en|ru
请指教。感谢您的时间和知识。
更新 1:
我需要传递 GET 参数,因为我有两个页面:[1]search
和 [2] searchShow
(仅显示一个项目的详细视图),并且在该页面上有返回到页面 [1] 的链接需要“term”参数为了显示具有相同参数的搜索
一个例子:
- 在搜索页面 [1] 上,当我按下提交按钮时,在输入搜索字词后,我得到类似的 URL
http://localhost:8000/en/search?term=productName
在与搜索结果列表相同的页面上,有一些指向详细信息页面的链接 [2]。链接是用
path()
功能制作的<li><a class="button secondary small" href="{{ path('goods_search_show', {'id': search_item.id, 'term': term}) }}">{{ "goods.button.view"|trans }}</a></li>
并产生类似的 URL
http://localhost:8000/en/search-show/162/productName
term
在此页面 [2] 上,我必须使用从搜索页面 [1] 的链接中传递的搜索参数创建返回到搜索页面 [1]的链接。为此,我path()
再次使用函数<li><a class="button secondary small" href="{{ path('goods_search', app.request.get('_route_params')|merge({'term': term})) }}">{{ "goods.button.backToList"|trans }}</a></li>
并获得类似的网址
http://localhost:8000/en/search/productName
现在 - 通过该链接,我返回搜索页面 [1] 并显示以前的搜索结果。
然后,当尝试另一个搜索词并按下提交按钮时,我得到生成的 URL [A] 而不是 [B] 或 [C]
[A] http://localhost:8000/en/search/productName?term=anotherProductName [B] http://localhost:8000/en/search/anotherProductName [C] http://localhost:8000/en/search?term=anotherProductName
正如您从路由中看到的那样 - 路由转到
goods_search
. 对 执行搜索productName
,但anotherProductName
完全忽略(实际上term
是 URL 的一部分)。
我觉得必须有比使用 POST 或传入term
会话更好的解决方案。也许 Apache 服务器的文件的一些附加参数.htaccess
可以解决错误的 URL 变得更好。
更新 2:
我听取了Alvin Bunk的建议并实施了表单并更新了模板以使用表单小部件而不是基本的 html。
不幸的是,当我按搜索而不是漂亮的 URL 时,我得到了这个
`http://localhost:8000/ru/search?term=productName&submit=&_token=IvGAvN-nCR40-PKm--rA92AzGXTbI94y2rDCPZxa5D0`
当我将术语更改为 otherProductName 我得到
`http://localhost:8000/ru/search/productName?term=otherProductName&submit=&_token=IvGAvN-nCR40-PKm--rA92AzGXTbI94y2rDCPZxa5D0`
所以问题保持不变 - 意思term
是 URL 的一部分两次。
那么也许这个问题真的是路由或 URL 重写问题?(问题中提到了我使用的路由,并且.htaccess
文件是 Symfony3 附带的默认文件)。
我的表格
{{ form_start(form, {'attr': {'id': 'search-form'}, 'action': path('goods_search', {'_locale': lang, 'term': term}), 'method': 'GET'}) }}
<fieldset>
{{ form_row(form.term, {'name': term, 'attr': {'class': 'input-term'}}) }}
{{ form_row(form.submit, {'attr': {'class': 'input-submit small success'}}) }}
</fieldset>
{{ form_end(form) }}
这是 ItemType
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class ItemType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('term', TextType::class, array('mapped' => false, 'label' => false))
->add('submit', SubmitType::class, array('label' => 'Test label for SUBMIT button'))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Item',
));
}
public function getBlockPrefix()
{
return null;
}
}
这就是我创建表单的方式SearchController
$item = new Item();
$form = $this->createForm(ItemType::class, $item);
return $this->render('search/search_show.html.twig', array('term' => $term, 'form' => $form->createView()));
更新 3:
在应用两个站点后,我的问题找到了几个解决方法似乎按预期工作。
解决方法 1
简单地省略表单的 action 属性会使 URL 工作并覆盖term
URL,而不是显示两次。
我现在的表格
{{ form_start(form, {'attr': {'id': 'search-form'}, 'method': 'GET'}) }}
<fieldset>
{{ form_row(form.term, {'name': term, 'attr': {'class': 'input-term'}}) }}
{{ form_row(form.submit, {'attr': {'class': 'input-submit small success'}}) }}
</fieldset>
{{ form_end(form) }}
解决方法 2
在第二页上有返回到搜索页面的链接term
,其 URL 如下所示search?term=productName
因此,在第二个搜索页面模板中,我使用以下代码创建了自定义的丑陋 URL :
{% set link_back = path('goods_search') ~ '?term=' ~ term %}
<li><a href="{{ link_back }}">link back to main search page</a></li>
term
而不是与路由参数合并
{% set link_back = path('goods_search', app.request.get('_route_params')|merge({'term': term})) %}
<li><a href="{{ link_back }}">link back to main search page</a></li>