You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 5.4 base.twig导航栏搜索表单提交无结果解决方法

问题核心原因

你遇到的提交失效问题是以下几个点叠加导致的:

  • 用{{ render(controller()) }}子请求渲染表单时,没有给表单显式指定提交地址,Form组件会自动把当前浏览的页面URL作为表单action,提交请求根本没发到你写的app_search路由,而是发到了当前页(比如首页、列表页),这些页面对应的控制器没有处理搜索表单的逻辑,自然不会返回结果。
  • 子请求本身会生成独立的Request实例,即便请求发到了正确路由,嵌套渲染时也容易出现表单提交状态识别异常的问题。
  • 额外的代码bug:结果模板里{% for Gry in Gry %}循环变量和结果集重名,即便拿到数据也会渲染异常。
可直接落地的实现方案

方案1:修正原有Form组件逻辑(保留FormBuilder用法)

1. 给表单显式绑定提交路由和请求方法

修改控制器中创建表单的代码,固定表单提交地址,避免子请求自动获取当前URL的问题,搜索场景推荐用GET方法,避免重复提交弹窗、支持搜索结果分享:

#[Route('/search/SBresult', name: 'app_search')]
public function searchBar(Request $request, EntityManagerInterface $entityManager): Response
{
    // 移除方法参数里默认的$Nazwa定义,完全从请求取数据
    $form = $this->createFormBuilder([], [
        'action' => $this->generateUrl('app_search'), // 固定提交到搜索路由
        'method' => 'GET',
    ])
    ->add('Nazwa', TextType::class, [
        'required' => false, 
        'label' => 'wpisz nazwę gry', 
        'label_attr'=> ['class'=>'text-white ps-3'], 
        'attr' => ['class'=>'form-control form-control-lg']
    ])
    ->getForm();

    $form->handleRequest($request);
                
    if ($form->isSubmitted() && $form->isValid()) { 
        $Nazwa = $form->get('Nazwa')->getData(); 
        $Gry = $entityManager->getRepository(Gra::class)->findGra($Nazwa);
        return $this->render('search/SBresult.html.twig', ['Gry' => $Gry]);
    }     
    // 这个模板只返回表单片段,供base模板嵌入用,不要加全局html/body标签
    return $this->render('search/searchBar.html.twig', ['form' => $form->createView()]); 
}

2. 修正模板代码

  • 嵌入用的表单片段模板search/searchBar.html.twig,只保留表单渲染逻辑,不要套完整页面结构:
{{ form_start(form, {attr: {class: 'd-flex'}}) }}
    {{ form_label(form.Nazwa) }}
    {{ form_widget(form.Nazwa) }}
    <button type="submit" class="btn btn-primary ms-2 align-self-center">搜索</button>
    {{ form_rest(form) }}
{{ form_end(form) }}
  • 结果页模板search/SBresult.html.twig修正循环变量重名问题,且必须继承base模板:
{% extends 'base.html.twig' %}

{% block body %}
<h1>搜索结果</h1>
{% if Gry is empty %}
    <div class="alert alert-info">没有找到匹配的游戏</div>
{% else %}
    <div class="game-list">
    {# 注意循环单个变量不要和结果集重名 #}
    {% for gra in Gry %}
        <div class="game-item">
            {# 这里替换成你自己的游戏实体字段输出逻辑 #}
            <h3>{{ gra.nazwa }}</h3>
        </div>
    {% endfor %}
    </div>
{% endif %}
{% endblock %}

3. base模板中的渲染代码保持不变即可

{{ render(controller('App\\Controller\\SearchController::searchBar')) }}

方案2:静态表单实现(更简单稳定,无嵌套请求问题)

导航栏的单字段搜索完全不需要走子请求+FormBuilder渲染,直接写原生表单性能更高,完全规避子请求的所有坑,推荐使用:

1. 简化控制器代码

#[Route('/search/SBresult', name: 'app_search')]
public function searchBar(Request $request, EntityManagerInterface $entityManager): Response
{
    $keyword = trim($request->query->get('Nazwa', ''));
    $gry = [];
    if ($keyword) {
        $gry = $entityManager->getRepository(Gra::class)->findGra($keyword);
    }
    return $this->render('search/SBresult.html.twig', [
        'Gry' => $gry,
        'keyword' => $keyword
    ]);
}

2. 直接在base.twig.html导航栏对应位置写表单,删掉原来的render调用

<form action="{{ path('app_search') }}" method="get" class="d-flex">
    <label for="game-search" class="text-white ps-3 align-self-center">wpisz nazwę gry</label>
    <input 
        type="text" 
        id="game-search" 
        name="Nazwa" 
        class="form-control form-control-lg ms-2" 
        value="{{ app.request.query.get('Nazwa', '') }}"
        placeholder="输入游戏名称"
    >
    <button type="submit" class="btn btn-primary ms-2">搜索</button>
</form>

3. 结果页模板和方案1的写法一致即可,注意修正循环变量重名问题。


内容的提问来源于stack exchange,提问作者Magdalena Wójcik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:03:12