【发布时间】:2015-01-09 09:40:46
【问题描述】:
我有这种情况
实体
class Foo
{
/**
* @ORM\Id
* @ORM\Column(type="date")
*/
protected $date;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity"Bar", inversedBy="foo")
*/
protected $bar;
[...]
}
存储库
class FooRepository extends EntityRepository
{
public function dummyNameFunction()
{
$q = $this->createQueryBuilder('foo')
->//some dummy "components" added to builder
->getQuery()
;
//I need an ArrayCollection as I want to take advantage of
//Doctrine's ArrayCollection filter() function
return new ArrayCollection($q->getResult());
}
}
问题
只要我尝试从 db 中获取数据,我就会得到这个错误
ContextErrorException:可捕获的致命错误:DateTime 类的对象 无法转换为字符串 /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php 第 2504 行
对我来说这是“非常清楚”:从对象的Array 转换为ArrayCollection,Doctrine 想用实体的 id 索引全新的ArrayCollection,但是,因为关键是日期时间, PHP 本身没有提供__toString() 方法(或等效方法)。
我想到的可能解决方案:
- 添加一个整数字段作为 id。从
$date和$bar中删除 id 并设置约束以使它们唯一。缺点:我有一个完全没用的文件。 -
Register 一种学说自定义映射类型,基本上是带有 __toString 魔术方法的。第二个解决方案似乎有效,但不适用于 __toString() 魔术方法。这有点“黑客”,有点脏。您可以在下面找到解决方案 (*)Date。缺点:我现在不知道这是否有效,因为我还没有尝试过。
问题
- 与我的两种可能的解决方案相比,有人知道更好或“更快”的方法吗?
- (附带问题)这是一个“真正的”问题吗? Doctrine2 devel 可能没有考虑将日期作为键?
脏溶液(*)
首先你需要定义一个 Doctrine2 服装类型。你怎么能这样做?
我在 Doctrine\DBAL\Types 的包内创建了一个文件夹(以保持 Doctrine2 原始包结构的安全)。然后,在里面,我创建了这个类
<?php
namespace Company\BundleName\Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\DateType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class CustomDate extends DateType
{
private $date_value;
public function getName()
{
return 'custom_date';
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
$date = parent::convertToPHPValue($value, $platform);
$this->date_value = $date;
return $date->format('Y-m-d');
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return ($value !== null)
? $value : null;
}
}
然后我添加了一个 boot() 方法来捆绑引导文件(您需要在 AppKernel.php 中注册捆绑的文件)
public function boot()
{
$em = $this->container->get('doctrine.orm.entity_manager');
Type::addType('custom_date', 'Company\BundleName\Doctrine\DBAL\Types\CustomDate');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('custom_date','custom_date');
}
在那之后,我有了 mod。 Foo 的$date 变量的映射
/**
* @ORM\Id
* @ORM\Column(type="custom_date")
*/
protected $date;
注意:如果你使用任何类型提示,记得正确更改getter和setter
【问题讨论】:
-
根据我的经验,使用
auto_incrementids 作为表的主键总是一个好主意...任何其他字段都会让您头疼。 -
@OscarPérez:如果他们给你机会使用其他类型的 id(s) 我相信这些类型和整数一样可以正常工作,所以我在这里等待知道如何修复的人无需添加额外的字段。来吧,应该有方法的! :) PS.:更新了我的问题,第二种方法没有奏效
标签: symfony doctrine-orm