EasyAdminBundle NumberField 是舍入纬度和经度小数
Posted
技术标签:
【中文标题】EasyAdminBundle NumberField 是舍入纬度和经度小数【英文标题】:EasyAdminBundle NumberField is rounding latitude and longitude decimals 【发布时间】:2021-08-19 18:48:41 【问题描述】:我在 php Symfony 项目中使用 EasyAdminBundle。在管理员中,我在编辑和详细信息视图中显示 NumberFields 纬度和经度时出现问题,因为 EasyAdmin 不显示存储在数据库中的值,这些值仅四舍五入为 3 位小数,而不是存储在数据库中的所有小数.
你可以在下面看到我的 ActionCrudController:
<?php
namespace App\Controller\Admin;
use App\Entity\Action;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Symfony\Component\Routing\Annotation\Route;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TelephoneField;
use EasyCorp\Bundle\EasyAdminBundle\Field\UrlField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action as EasyCorpAction;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
class ActionCrudController extends AbstractCrudController
public static function getEntityFqcn(): string
return Action::class;
public function configureFields(string $pageName): iterable
return [
IdField::new('id')->hideOnForm(),
TextField::new('name'),
TextEditorField::new('description')->hideOnIndex(),
TextareaField::new('address'),
TextField::new('city')->hideOnIndex(),
TextField::new('postal_code')->hideOnIndex(),
TextField::new('email'),
TelephoneField::new('phone'),
UrlField::new('website')->hideOnIndex(),
TextEditorField::new('opening_hours'),
NumberField::new('latitude')->hideOnIndex(),
NumberField::new('longitude')->hideOnIndex(),
TextareaField::new('public_accueilli_detail')->hideOnIndex(),
TextareaField::new('modalite_acces')->hideOnIndex(),
TextareaField::new('tarif')->hideOnIndex(),
TextField::new('slug')->hideOnIndex(),
DateTimeField::new('created_at')->onlyOnIndex(),
DateTimeField::new('updated_at')->onlyOnIndex(),
AssociationField::new('operateur')->setRequired(true),
AssociationField::new('sousthematiques'),
AssociationField::new('public_accueilli')->hideOnIndex(),
];
public function configureActions(Actions $actions): Actions
return $actions
->add(Crud::PAGE_INDEX, EasyCorpAction::DETAIL);
你可以在这里看到我的动作实体,其中纬度和经度是浮动的:
<?php
namespace App\Entity;
use App\Repository\ActionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=ActionRepository::class)
* @ORM\HasLifecycleCallbacks()
* @ORM\Table("action")
*/
class Action
use Timestamps;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $address;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $city;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $postal_code;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $email;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $phone;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $website;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $opening_hours;
/**
* @ORM\Column(type="float")
*/
private $latitude;
/**
* @ORM\Column(type="float")
*/
private $longitude;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $public_accueilli_detail;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $modalite_acces;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $tarif;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $slug;
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $updated_at;
/**
* @ORM\ManyToOne(targetEntity=Operateur::class, inversedBy="actions")
* @ORM\JoinColumn(nullable=false)
*/
private $operateur;
/**
* @ORM\ManyToMany(targetEntity=SousThematique::class, inversedBy="actions")
*/
private $sousthematiques;
/**
* @ORM\OneToMany(targetEntity=HoraireAction::class, mappedBy="action")
*/
private $horaire_actions;
/**
* @ORM\ManyToMany(targetEntity=PublicAccueilli::class, inversedBy="actions")
*/
private $public_accueilli;
public function __construct()
$this->sousthematiques = new ArrayCollection();
$this->horaire_actions = new ArrayCollection();
$this->public_accueilli = new ArrayCollection();
public function getId(): ?int
return $this->id;
public function getName(): ?string
return $this->name;
public function setName(string $name): self
$this->name = $name;
return $this;
public function getDescription(): ?string
return $this->description;
public function setDescription(?string $description): self
$this->description = $description;
return $this;
public function getAddress(): ?string
return $this->address;
public function setAddress(?string $address): self
$this->address = $address;
return $this;
public function getCity(): ?string
return $this->city;
public function setCity(?string $city): self
$this->city = $city;
return $this;
public function getPostalCode(): ?string
return $this->postal_code;
public function setPostalCode(?string $postal_code): self
$this->postal_code = $postal_code;
return $this;
public function getEmail(): ?string
return $this->email;
public function setEmail(?string $email): self
$this->email = $email;
return $this;
public function getPhone(): ?string
return $this->phone;
public function setPhone(?string $phone): self
$this->phone = $phone;
return $this;
public function getWebsite(): ?string
return $this->website;
public function setWebsite(?string $website): self
$this->website = $website;
return $this;
public function getOpeningHours(): ?string
return $this->opening_hours;
public function setOpeningHours(?string $opening_hours): self
$this->opening_hours = $opening_hours;
return $this;
public function getLatitude(): ?float
return $this->latitude;
public function setLatitude(float $latitude): self
$this->latitude = $latitude;
return $this;
public function getLongitude(): ?float
return $this->longitude;
public function setLongitude(float $longitude): self
$this->longitude = $longitude;
return $this;
public function getPublicAccueilliDetail(): ?string
return $this->public_accueilli_detail;
public function setPublicAccueilliDetail(?string $public_accueilli_detail): self
$this->public_accueilli_detail = $public_accueilli_detail;
return $this;
public function getModaliteAcces(): ?string
return $this->modalite_acces;
public function setModaliteAcces(?string $modalite_acces): self
$this->modalite_acces = $modalite_acces;
return $this;
public function getTarif(): ?string
return $this->tarif;
public function setTarif(?string $tarif): self
$this->tarif = $tarif;
return $this;
public function getSlug(): ?string
return $this->slug;
public function setSlug(?string $slug): self
$this->slug = $slug;
return $this;
public function getCreatedAt(): ?\DateTimeInterface
return $this->created_at;
public function setCreatedAt(\DateTimeInterface $created_at): self
$this->created_at = $created_at;
return $this;
public function getUpdatedAt(): ?\DateTimeInterface
return $this->updated_at;
public function setUpdatedAt(?\DateTimeInterface $updated_at): self
$this->updated_at = $updated_at;
return $this;
public function getOperateur(): ?Operateur
return $this->operateur;
public function setOperateur(?Operateur $operateur): self
$this->operateur = $operateur;
return $this;
/**
* @return Collection|SousThematique[]
*/
public function getSousthematiques(): Collection
return $this->sousthematiques;
public function addSousthematique(SousThematique $sousthematique): self
if (!$this->sousthematiques->contains($sousthematique))
$this->sousthematiques[] = $sousthematique;
return $this;
public function removeSousthematique(SousThematique $sousthematique): self
$this->sousthematiques->removeElement($sousthematique);
return $this;
/**
* @return Collection|HoraireAction[]
*/
public function getHoraireActions(): Collection
return $this->horaire_actions;
public function addHoraireAction(HoraireAction $horaireAction): self
if (!$this->horaire_actions->contains($horaireAction))
$this->horaire_actions[] = $horaireAction;
$horaireAction->setAction($this);
return $this;
public function removeHoraireAction(HoraireAction $horaireAction): self
if ($this->horaire_actions->removeElement($horaireAction))
// set the owning side to null (unless already changed)
if ($horaireAction->getAction() === $this)
$horaireAction->setAction(null);
return $this;
/**
* @return Collection|PublicAccueilli[]
*/
public function getPublicAccueilli(): Collection
return $this->public_accueilli;
public function addPublicAccueilli(PublicAccueilli $public_accueilli): self
if (!$this->public_accueilli->contains($public_accueilli))
$this->public_accueilli[] = $public_accueilli;
return $this;
public function removePublicAccueilli(PublicAccueilli $public_accueilli): self
$this->public_accueilli->removeElement($public_accueilli);
return $this;
public function __toString()
return $this->name;
我一直在尝试几种解决方案,例如:
修改ActionCrudController中的经纬度表单域 -->例如。 NumberField::new('longitude')->hideOnIndex()->setNumDecimals(12),
但这并不是我想要的,因为在详细信息和编辑视图中并没有显示存储在数据库中的确切浮点数。如果浮点数少于 12 位小数,则加 0。
我尝试的另一种可能性是修改动作实体:@ORM\Column(type="float", scale=15) 私人$纬度;
但它也不起作用。
您知道如何在 EasyAdmin 的“编辑”和“详细信息”视图中以我的数据库中的确切小数位数显示纬度和经度浮点数吗?
你知道我可以在哪里配置 EasyAdmin 中 NumberField 中显示的小数位数吗?
提前感谢您的帮助!
【问题讨论】:
【参考方案1】:尝试在 Doctrine 注释中添加精度(和小数类型)?
/**
* @ORM\Column(type="decimal", precision=9, scale=7)
*/
protected $latitude;
/**
* @ORM\Column(type="decimal", precision=10, scale=7)
*/
protected $longitude;
您可以通过调整它们来选择所需的精确度。
回复您最近的回答(关于您的数据库错误): 您收到此错误是因为您的数据库中的数据存储在更准确的级别(例如 -120.923828919)
精度 = 总位数(不考虑小数) 比例=小数点后多少位数
mysql 要求 Scale
您只需要调整您的精度 8 将只允许 8 个数字,例如最大值可能是 999.99999。纬度的坐标从 -90 到 90,经度的坐标从 -180 到 180,这取决于您真正需要的小数点后多远。我已经修改了我的价值观,使其更加慷慨。
抱歉,我还不能发表评论,但您可以尝试添加自定义表单类型选项吗?我不认为这取决于 EasyAdmin 本身,而是从 Symfony 继承的 NumberType 字段。文档似乎指向使用“比例”表单类型选项。
也许
NumberField::new('latitude')->hideOnIndex()->setFormTypeOption('scale', 8)
如果您需要添加更多选项,只需使用复数版本->setFormTypeOptions(['scale' => 8])
。
指向此功能的直接文档链接: NumberType#scale
【讨论】:
【参考方案2】:目前没有使用 EasyAdmin 的干净方法。
一个快速而肮脏的解决方法是编辑 NumberConfigurator.php (EasyCorp\Bundle\EasyAdminBundle\Field\Configurator)。
在此处将 'fraction_digit' 替换为 'max_fraction_digit':
// $formatterAttributes['fraction_digit'] = $scale;
$formatterAttributes['max_fraction_digit'] = $scale;
然后调用 NumberField::new('longitude')->hideOnIndex()->setNumDecimals(12), 应该按你的意愿工作。
或者,您可以在 NumberField.php 中添加一个 setMaxNumDecimals 方法,并相应地修改源代码到 NumberConfigurator.php。
(如果您愿意,请提交合并请求)
【讨论】:
以上是关于EasyAdminBundle NumberField 是舍入纬度和经度小数的主要内容,如果未能解决你的问题,请参考以下文章
使用 FOS 为 EasyAdminBundle 设置安全性
EasyAdminBundle NumberField 是舍入纬度和经度小数
FOSUserBundle 在 EasyAdminBundle 中管理((“用户”实体必须使用“类”选项定义其关联的 Doctrine 实体类))Symfony