gpt4 book ai didi

php - Doctrine 记录的深拷贝

转载 作者:可可西里 更新时间:2023-11-01 13:32:16 26 4
gpt4 key购买 nike

我想对 symfony 项目中的条令记录进行深度复制/克隆。现有的 copy($deep) 方法不能与 $deep=true 一起正常工作。

举个例子,让我们看一下类类(class)。本课有开始日期和结束日期,中间有几次休息时间。这间教室在一座大楼里。

lesson-break 是一对多的关系,所以很多课间休息都可以在一节课中。建课是多对一的关系,所以一个类只能在一栋楼里。

如果我想复制房间,也应该复制休息时间。建筑物应该保持不变(此处没有副本)。

我在网上找到了一些示例,这些示例创建了一个从 sfDoctrineRecord 扩展并覆盖复制方法的 PHP 类。

我尝试的是:

class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);
if (!$deep)
return $ret;

// ensure to have loaded all references (unlike Doctrine_Record)
foreach ($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if ($relation->getType() == Doctrine_Relation::MANY) {
if (empty($this->$name))
$this->loadReference($name);

// do the deep copy
foreach ($this->$name as $record)
$ret->{$name}[] = $record->copy($deep);
}
}
return $ret;
}
}

现在这会导致失败:Doctrine_Connection_Mysql_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY'

因此我需要“清空”新记录的 ID ($ret),因为这应该是一条新记录。我可以/应该在哪里以及如何做?

更新:错误已通过以下代码修复:

class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);

if($this->Table->getIdentifierType() === Doctrine_Core::IDENTIFIER_AUTOINC) {
$id = $this->Table->getIdentifier();
$this->_data[$id] = null;
}

if(!$deep) {
return $ret;
}

// ensure to have loaded all references (unlike Doctrine_Record)
foreach($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if($relation->getType() == Doctrine_Relation::MANY) {
if(empty($this->$name)) {
$this->loadReference($name);
}

// do the deep copy
foreach($this->$name as $record) {
$ret->{$name}[] = $record->copy($deep);
}
}
}

return $ret;
}
}

但是效果不是很好。在 DoctrineCollection 类(class)->中断中,所有新的中断都可以。但是它们没有保存在数据库中。我想复制一节课,并在它的时间上增加 7 天:

foreach($new_shift->Breaks as $break) {
$break->start_at = $this->addOneWeek($break->start_at);
$break->end_at = $this->addOneWeek($break->end_at);
$break->save();
}

如您所见,中断已保存,但它们似乎不在数据库中。

最佳答案

这对我有用,它是问题代码的变体:

public function realCopy($deep = false) {
$ret = self::copy(false);

if(!$deep) {
return $ret;
}

// ensure to have loaded all references (unlike Doctrine_Record)
foreach($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if($relation->getType() == Doctrine_Relation::MANY) {
if(empty($this->$name)) {
$this->loadReference($name);
}

// do the deep copy
foreach($this->$name as $record) {
$ret->{$name}[] = $record->realCopy($deep);
}
}
}

// this need to be at the end to ensure Doctrine is able to load the relations data
if($this->Table->getIdentifierType() === Doctrine_Core::IDENTIFIER_AUTOINC) {
$id = $this->Table->getIdentifier();
$this->_data[$id] = null;
}

return $ret;
}

我不敢相信我在 2017 年使用 Doctrine 1.2。

关于php - Doctrine 记录的深拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3439792/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com