上下文
我需要使用Doctrine 2.3(使用PHP 5.4)将一个实体保持在会话中,一旦设置了$_SESSION
变量,我就会遇到问题。
代码
我有以下课程:
Persistente
用于保存有关持久类的信息的超类。
/**
* @MappedSuperclass
*/
abstract class Persistente
{
public function __construct()
{}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
}
Persona
保存一个人的基本信息。
/**
* @Entity
* @AttributeOverrides({
* @AttributeOverride(name="id",
* column=@Column(
* name="Persona_Id",
* type="integer"
* )
* )
* })
*/
class Persona extends Persistente
{
...
public function getContInformacion()
{
return $this->contInformacion;
}
public function setContInformacion(ContenedorInformacion $contInformacion)
{
$this->contInformacion = $contInformacion;
}
...
/**
* @OneToOne(targetEntity="ContenedorInformacion", cascade={"all"} )
* @JoinColumn(name="ContInfo_Id", referencedColumnName="ContInfo_Id")
*/
private $contInformacion;
}
参赛者信息
类,该类包含有关人员的信息,这些信息可以根据某些验证规则动态添加到对象中。
/**
* @Entity
* @AttributeOverrides({
* @AttributeOverride(name="id",
* column=@Column(
* name="ContInfo_Id",
* type="integer"
* )
* )
* })
*/
class ContenedorInformacion extends Persistente
{
...
/**
* @OneToMany(targetEntity="UnidadInformacion", mappedBy="contInformacion", cascade={"all"}, indexBy="clave")
*/
private $unidadesInformacion;
/**
* @OneToMany(targetEntity="Rol", mappedBy="contInformacion", cascade={"all"}, indexBy="clave")
*/
private $roles;
}
问题
每当我将Persona
添加到会话中时,就会执行以下代码:
public function login(Persona $t)
{
if ($this->autorizar($t) === false) {
return false;
}
$dao = new DAOManejadorMsSql();
$daoPersona = $dao->fabricarDAO("'Codesin'Colegios'Personas'Persona");
$t = $this->buscarPersona($t);
$daoPersona->soltar($t);
$dao->cerrar();
$_SESSION['usuario'] = $t;
if ($t->getContInformacion()->existeRol('SYSADMIN') === true) {
return 'SYSADMIN';
}
}
soltar()
从EntityManager执行detach()
方法,从而有效地使实体处于非托管状态。然而,Persona
中的ContenedorInformacion
对象是Doctrine生成的代理,而不是所需对象。为什么会发生这种情况?事先谢谢。
编辑:这就是错误。
Warning: require(C:'xampp'htdocs/Zeus/lib/vendor/DoctrineProxies/__CG__/Codesin/Colegios/Personas/ContenedorInformacion.php): failed to open stream: No such file or directory in C:'xampp'htdocs'Zeus'Common'Utils'autoload.php on line 8
Fatal error: require(): Failed opening required 'C:'xampp'htdocs/Zeus/lib/vendor/DoctrineProxies/__CG__/Codesin/Colegios/Personas/ContenedorInformacion.php' (include_path='.;C:'xampp'php'PEAR') in C:'xampp'htdocs'Zeus'Common'Utils'autoload.php on line 8
我不得不使用一种非常粗糙的方法。
我发现了以下内容:考虑到我不会立即重新附加信息,我重新制作了另一个ContenedorInformacion
,它包含与代理完全相同的信息。考虑到ArrayCollection
没有使用代理,而是使用整个对象,我这样做了。
public function login(Persona $t)
{
if ($this->autorizar($t) === false) {
return false;
}
$dao = new DAOManejadorMsSql();
$daoPersona = $dao->fabricarDAO("'Codesin'Colegios'Personas'Persona");
$t = $this->buscarPersona($t);
$daoPersona->soltar($t);
$dao->cerrar();
/***** NEW LINES START HERE *****/
$contInfo = new ContenedorInformacion();
$contInfo->setId($t->getContInformacion()->getId());
$contInfo->setUnidadesInformacion(new ArrayCollection($t->getContInformacion()->getUnidadesInformacion()->toArray()));
$contInfo->setRoles(new ArrayCollection($t->getContInformacion()->getRoles()->toArray()));
$t->setContInformacion($contInfo);
/***** NEW LINES END HERE *****/
$_SESSION['usuario'] = $t;
if ($t->getContInformacion()->existeRol('SYSADMIN') === true) {
return 'SYSADMIN';
}
}
它很脏,但很有魅力。