我正在使用:
我在教义查询中使用 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重写或路由问题
我总是需要漂亮的 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
请指教。 感谢您的时间和知识。
我需要传递 GET 参数,因为我有两个页面:[1]
search
和 [2] searchShow
(仅显示一项的详细视图),并且该页面上有返回页面 [1] 的链接需要“term”参数才能显示具有相同参数的搜索
一个例子:
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>
并生成类似
http://localhost:8000/en/search-show/162/productName
在此页面 [2] 上,我必须使用搜索参数
term
创建返回搜索页面 [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 变得更好。
我听取了 Alvin Bunk 的建议,并实现了表单并更新了模板以使用表单小部件而不是基本的 html。
不幸的是,当我按搜索而不是漂亮的网址时,我得到了这个
`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()));
找到了解决我的问题的几个解决方法,在应用两个网站后似乎都按预期工作。
解决方法 1
只需省略表单的 action 属性即可使 URL 正常工作并覆盖 URL 中的
term
,而不是显示两次。
我现在的表格
{{ 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
在第二页上有返回搜索页面的链接,URL 中带有
term
,如 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>
使用GET方法出现这样的URL是正常的,尝试使用POST。
但最好是使用 Ajax。
您可以在树枝模板中执行类似的操作:
{{ form_start(form,
{'action': path('/en/search-show',
{'id':search_items.getID,
'term':term}),
'method': 'GET'}) }}
然后,我喜欢在控制器中使用注释(而不是 YAML 文件)并执行类似的操作来处理参数:
/**
* @Route("/search-show/{id}/{term}",
* defaults={"id" = 0,"term" = 0},
* name="submitPetHasProgram")
*/
public function searchShowAction($id, $term, Request $request){
...
那么 URL 将如下所示: http://localhost:8000/lv/search/someId/someTerm
我显示了“someId”和“someTerm”,但这是从树枝模板传入的实际 id 和术语。