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

Symfony表单双日期选择器异常及实体字段匹配问题求助

问题根源

  1. 表单仅显示end_date:StatisticsType中重复调用->add('date'),重复字段名导致第一个日期选择器被覆盖,最终只渲染最后一个。
  2. 用dateFrom/dateTo提示字段不存在:表单绑定的RequestsN实体无对应字段,Symfony表单自动映射实体属性时找不到匹配项报错。

解决方案

通过**数据传输对象(DTO)**承载筛选参数(不依赖实体字段),修改表单类绑定DTO,修正代码拼写错误,调整控制器逻辑适配新结构。


1. 创建筛选DTO

新建src/DTO/StatisticsFilter.php,专门存放筛选条件:

<?php

namespace App\DTO;

use App\Entity\WorldCountries;
use DateTimeInterface;

class StatisticsFilter
{
    private ?DateTimeInterface $dateFrom = null;
    private ?DateTimeInterface $dateTo = null;
    private ?WorldCountries $country = null;

    public function getDateFrom(): ?DateTimeInterface
    {
        return $this->dateFrom;
    }

    public function setDateFrom(?DateTimeInterface $dateFrom): self
    {
        $this->dateFrom = $dateFrom;
        return $this;
    }

    public function getDateTo(): ?DateTimeInterface
    {
        return $this->dateTo;
    }

    public function setDateTo(?DateTimeInterface $dateTo): self
    {
        $this->dateTo = $dateTo;
        return $this;
    }

    public function getCountry(): ?WorldCountries
    {
        return $this->country;
    }

    public function setCountry(?WorldCountries $country): self
    {
        $this->country = $country;
        return $this;
    }
}

2. 修改StatisticsType

替换重复字段为dateFrom/dateTo,并绑定到DTO:

<?php

namespace App\Form;

use App\DTO\StatisticsFilter;
use App\Entity\WorldCountries;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateType;

class StatisticsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('dateFrom', DateType::class, [
                'widget' => 'single_text',
                'html5' => false,
                'attr' => ['class' => 'js-datepicker'],
                'label' => 'start_date',
                'row_attr' => [
                    'class' => 'input-daterange'
                ]
            ])
            ->add('dateTo', DateType::class, [
                'widget' => 'single_text',
                'html5' => false,
                'attr' => ['class' => 'js-datepicker'],
                'label' => 'end_date',
                'row_attr' => [
                    'class' => 'input-daterange'
                ]
            ])
            ->add('country', EntityType::class, [
                'class' => WorldCountries::class,
                'choice_label' => function (WorldCountries $country) {
                    return $country->getcName();
                }
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => StatisticsFilter::class,
        ]);
    }
}

3. 修正RequestsN实体拼写错误

修正类名拼写和驼峰命名不规范问题:

#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $date = null;

#[ORM\ManyToOne(inversedBy: 'country')]
private ?WorldCountries $country = null;

public function getDate(): ?\DateTimeInterface
{
    return $this->date;
}

public function setDate(\DateTimeInterface $date): self
{
    $this->date = $date;
    return $this;
}

public function getCountry(): ?WorldCountries
{
    return $this->country;
}

public function setCountry(?WorldCountries $country): self
{
    $this->country = $country;
    return $this;
}

4. 调整RequestsNController逻辑

使用DTO实例化表单,提交时从DTO获取参数:

#[Route('/requestsn')]
class RequestsNController extends AbstractController
{
    #[Route('/', name: 'app_requestsN', methods: ['GET', 'POST'])]
    public function index(RequestsNRepository $r_repo, Request $request): Response
    {   
        $filter = new StatisticsFilter();
        $formStat = $this->createForm(StatisticsType::class, $filter);
        $dates = [];

        $formStat->handleRequest($request);
        if ($formStat->isSubmitted() && $formStat->isValid()) {
            $dates = $r_repo->getTotal(
                $filter->getDateFrom(),
                $filter->getDateTo(),
                $filter->getCountry()?->getcName()
            );
        }

        return $this->render('/requestsN/index.html.twig', [
            'dates' => $dates,
            'formStat' => $formStat->createView(),
        ]);
    }
}

5. Twig模板示例

确保完整渲染表单和统计结果:

{{ form_start(formStat) }}
    {{ form_row(formStat.dateFrom) }}
    {{ form_row(formStat.dateTo) }}
    {{ form_row(formStat.country) }}
    <button type="submit">统计</button>
{{ form_end(formStat) }}

{% if dates.counter is defined %}
    <p>请求总数:{{ dates.counter }}</p>
{% endif %}

内容的提问来源于stack exchange,提问作者Rene

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:30:30