0

我有一个绑定到 ZF / Laminas 表单的地址实体。

定义了一些属性。比如街道,乡村,......

/**
 * @var string
 *
 * @ORM\Column(type="string", length=2)
 */
protected $country;

/**
 * @var float
 *
 * @ORM\Column(type="float", nullable=true)
 */
protected $longitude;

/**
 * @var float
 *
 * @ORM\Column(type="float", nullable=true)
 */
protected $latitude;

以及通过 EventListener 强制地理定位的非存储属性

/**
 * @var bool
 */
protected $geolocation = true;

带访问器

/**
 * @param bool $geolocation
 *
 * @return self
 */
public function setGeolocation(bool $geolocation): self
{
    $this->geolocation = $geolocation;

    return $this;
}

问题是在通过访问器补水期间。“地理位置”的值来自字符串类型“1”或“0”(复选框)的形式

水合由 DoctrineObject 水合器进行,但属性不由 ORM 管理。因此,启用严格类型模式后,由于 setGeolocation() 参数类型而引发异常。

它应该与 an 一起使用,@ORM\Column(type="boolean")但我不想存储这个值。

如何定义实体属性而不在 db 中创建列?

4

1 回答 1

1

我认为你对 Doctrine 或 hydration 没有问题,你对类型转换有问题。

当该值来自Laminas\Form\Form对象时,您应该使用InputFilter过滤器将值转换为布尔值。然后ObjectHydratorfrom 应该从输入过滤器中获取值。

让我们看一下我的示例(为简单起见,我在这里不使用 Doctrine):

<?php

declare(strict_types=1);

class MyEntity
{

    private bool $mycheckbox = false;

    public function getMycheckbox(): bool
    {
        return $this->mycheckbox;
    }

    public function setMycheckbox(bool $mycheckbox): void
    {
        $this->mycheckbox = $mycheckbox;
    }

}

use Laminas\Form\Form;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Form\Element;
use Laminas\Filter;
use Laminas\Hydrator\ClassMethods as Hydrator;

class MyForm extends Form implements InputFilterProviderInterface
{

    public function init(): void
    {
        $this->add([
            'name'    => 'mycheckbox',
            'type'    => Element\Checkbox::class,
            'options' => [],
        ]);

        $this->setObject(new MyEntity());
        $this->setHydrator(new Hydrator());
    }

    public function getInputFilterSpecification(): array
    {
        return [
            'mycheckbox' => [
                'filters' => [
                    // this filter is the important part
                    [
                        'name'    => Filter\Boolean::class,
                        'options' => [],
                    ]
                ],
            ],
        ];
    }

}

$form = new MyForm();
$form->init();

$form->setData(['mycheckbox' => '1']);
var_dump($form->isValid());
var_dump($form->getInputFilter()->getValues());


var_dump($form->getObject());

这里的输出是:

bool(true)
array(1) {
   'mycheckbox' =>
   bool(true)
}

class MyEntity#9 (1) {
   private $mycheckbox =>
   bool(true)
}
于 2020-05-26T11:06:53.797 回答