Doctrine 2 定义 属性 类型而不创建列

Doctrine 2 define property type without column creation

我有一个绑定到 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;
}

问题出在通过辅助器补水期间。 "geolocation" 的值来自字符串类型“1”或“0”(复选框)的形式

Hydration 由 DoctrineObject hydrator 进行,但 属性 不由 ORM 管理。所以启用严格类型模式后,由于setGeolocation()参数类型抛出异常。

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

如何在不在数据库中创建列的情况下定义实体 属性?

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

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

让我们看一下我的示例(为了简单起见,我在这里不使用 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)
}