如何通过 Symfony 中的 Doctrine 存储十进制值

Tom*_*Tom 3 php symfony doctrine-orm

我在 Symfony 中有一个实体,其产品价格定义如下:

 /**
 * @var string
 *
 * @ORM\Column(name="price", type="decimal", precision=12, scale=2, nullable=true)
 *
 */
private $price;
Run Code Online (Sandbox Code Playgroud)

现在我想存储价格值2.50,但它四舍五入为2.00。我尝试将其添加为(float) 2.50(string) 2.50,但它总是四舍五入为2.00

看起来我无法存储比例值?

Mic*_*ick 5

将其存储为整数

是的,最好的是以分为单位存储它,因此作为整数。这里的技巧是使用DataTransformer.


Entity

/**
 * Price of the option (in cents)
 *
 * @ORM\Column(type="integer", nullable=true)
 */
protected $price = 0;

/**
 * @param int $price
 */
public function setPrice(?int $price): self
{
    $this->price = $price;

    return $this;
}

/**
 * @return int
 */
public function getPrice(): ?int
{
    return $this->price;
}
Run Code Online (Sandbox Code Playgroud)

Data Transformer

<?php

namespace App\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class CentToDollarTransformer implements DataTransformerInterface
{
    /**
     * Transforms cent to dollar amount.
     *
     * @param  int|null $priceInCent
     * @return double
     */
    public function transform($priceInCent)
    {
        if (null === $priceInCent) {
            return;
        }

        $priceInDollar = number_format(($priceInCent /100), 2, '.', ' ');

        return $priceInDollar;
    }

    /**
     * Transforms dollar to cent amount.
     *
     * @param  double|null $priceInDollar
     * @return int
     */
    public function reverseTransform($priceInDollar)
    {
        if (null === $priceInDollar) {
            return;
        }

        $priceInCent = (int)($priceInDollar * 100);

        return $priceInCent;
    }
}
Run Code Online (Sandbox Code Playgroud)

Form Type

use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use App\Form\DataTransformer\CentToDollarTransformer;

// ...

$builder->add('price', MoneyType::class, array(
    'scale' => 2,
    'currency' => null,
    'label' => 'form.price',
    'attr' => array(
        'min' => '0.00',
        'max' => '1000.00',
        'step' => '0.01'
    )
));

$builder->get('price')
    ->addModelTransformer(new CentToDollarTransformer());
Run Code Online (Sandbox Code Playgroud)