【问题标题】:Symfony3 ugly URL paths after submit (url rewrite or ruting)提交后 Symfony3 丑陋的 URL 路径(url 重写或路由)
【发布时间】: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:

我怀疑这可能是 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


    【解决方案1】:

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

    但最好还是使用 Ajax。

    【讨论】:

    • 我需要传递 GET 参数,因为我有两个页面:[1] search 和 [2] searchShow(仅显示一个项目的详细视图)并且在该页面上有返回页面的链接[1] 需要“term”参数才能显示具有相同参数的搜索。
    • 也许您可以使用 session 传递该参数?,这种或其他方式 - 如果您使用 get 方法,您的 url 将是错误的
    • 这里没有什么可以阻止您使用 POST 方法来获取您的搜索参数,然后呈现您的 searchShow,并使用一个后退按钮重定向您以前的视图,将您的术语作为参数传递
    • 我更新了我的问题以说明手头的问题。
    【解决方案2】:

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

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

    【讨论】:

    • 我采纳了您的建议(请参阅问题的更新 2)不幸的是结果仍然相同 - 意味着 term 是 URL 的一部分。
    猜你喜欢
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 2014-09-30
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多