2

我在用:

  • 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:

我怀疑,这可能是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] 上,当我按下提交按钮时,在输入搜索字词后,我得到类似的 URLhttp://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>
    

    并产生类似的 URLhttp://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 工作并覆盖termURL,而不是显示两次。

我现在的表格

{{ 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>
4

2 回答 2

0

你可以在你的树枝模板中做这样的事情:

{{ 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”,但将是来自 twig 模板的实际 id 和 term。

于 2016-05-28T20:30:02.583 回答
0

使用 GET 方法有这样的 URL 是正常的,请尝试使用 POST。

但最好的方法是使用 Ajax。

于 2016-05-27T20:29:48.323 回答