【发布时间】:2016-05-27 19:37:55
【问题描述】:
我正在使用:
- 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 重写 或 路由 问题
我总是需要漂亮的网址——不仅在手动输入网址时,而且在使用表单搜索产品时。
这是来自搜索控制器的相关代码:
// 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] 上,当我按下提交按钮时,在输入搜索字词后,我得到类似
http://localhost:8000/en/search?term=productName的 URL -
在与搜索结果列表相同的页面上,有一些链接到详细信息页面 [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这样的URL -
在此页面 [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这样的URL 现在 - 通过该链接我返回搜索页面 [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) }}
这是项目类型
<?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 正常工作并覆盖 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
在第二页有返回搜索页面的链接,网址中带有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>
【问题讨论】:
标签: php search doctrine-orm symfony symfony-2.8