Symfony2将实体对象序列化到会话


Symfony2 serialize entity object to session

我想将我的一个实体对象保存到会话中,但在这样做的过程中,我遇到了以下两个错误:

异常:Symfony''Bundle''FrameworkBundle''DataCollector ''RequestDataCollector::serialize()必须返回字符串或NULL

ErrorException:注意:serialize():"id"作为成员返回__sleep()中的变量,但在中不存在/var/www/clients/client71/web256/web/dev_fd/kkon/vvendor/symfony/src/symfony/Component/HttpKernel/DataCollector第29行

我的代码是这样的:

$offer = $this->getEntityManager()->getRepository('KkuponMainBundle:Offer')->find($offer_id);
$request->getSession()->set('offer', $offer);

我怎么能做对呢?

谢谢。

更新在Rowgm的帮助下,我可以通过将属性设置为protected而不是private来解决这个问题。我遇到的唯一问题是,在从会话中读取实体后,EntityManager并不知道它,如果我将对象(从会话中)添加到另一个对象(它们之间存在OneToMany关系),它将不起作用。

<?php
$offer = $this->get('session')->get('offer');
$coupon = new Coupon();
$coupon->setOffer($offer);
$this->em->persist($coupon);
$this->em->flush();

这引发了一个错误,因为优惠券有一个对象属性,根据EntityManager,该属性不在数据库中(实际上它在数据库中,我从数据库中放入会话)。

<?php
$offer = $this->get('session')->get('offer');
echo $this->em->getUnitOfWork()->isInIdentityMap($offer) ? "yes":"no"; //result: no

一种解决方案可以是:$offer = $this->em->merge($offer);

但这似乎不是最好的一次。我希望我的EntityManager能够感知存储在会话中的实体对象,而无需每次都告诉它。知道吗?

您可以通过将任何实体的所有属性和关系从private设置为protected来序列化它们。

即使您已将所有属性设置为protected,symfony2也可能存在常见问题:您必须重新生成已更改实体的代理。要执行此操作,只需清除缓存即可。对于开发环境

app/console cache:clear

即使如您所说"它包含许多外部对象,甚至包含外部实体的ArrayCollections",它也能工作。

不建议序列化实体,正如您在Doctrine文档中看到的那样。您应该实现Serializable接口并手动序列化/反序列化实体数据。

您可以通过重写__sleep方法来排除不必要的字段:

public function __sleep() {
    // these are field names to be serialized, others will be excluded
    // but note that you have to fill other field values by your own
    return array('id', 'username', 'password', 'salt');
}