数组中的分离变量
dissociated variables in array
我对 php 变量有疑问。我使用的代码如下所示:
for($i = 0; $i <= $nbRecurrence; $i++) {
$res = new Reservation();
$res->setDateDebut($DateDebut->add(new \DateInterval('P1D')));
$res->setDateFin($DateFin->add(new \DateInterval('P1D')));
$lesRes[] = $res;
$this->app['orm.ems']['gestionReservationAuto']->persist($res);
$this->app['orm.ems']['gestionReservationAuto']->flush();
}
问题是,虽然我把数组中的每一个元素都加进去了,但是当我用一个var_dump
进行分析时,$lesRes
中的所有$res
都是相同的。数据库中注册的数据还不同...
我怎样才能拥有一个 $res
不喜欢的数组?
(如果我请求将我刚刚添加到数据库中的项目,我有同样的问题,我有一个 x 元素数组 $res
,它们都是相同的。)
我猜 $DateDebut
是一个 DateTime
对象。
我也猜 Reservation::setDateDebut()
看起来像:
class Reservation
{
private $dateDebut;
public function setDateDebut(DateTime $dateDebut)
{
$this->dateDebut = $dateDebut;
}
}
让我们再次编写使用它的代码:
$res = new Reservation();
$res->setDateDebut($DateDebut->add(new \DateInterval('P1D')));
您错过的是 DateTime::add()
不会创建新的 DateTime
对象,而是 returns 对当前对象的引用(即 return $this;
)。
这意味着在每次迭代中,您更改对象 $DateDebut
的值,然后将其传递给 Reservation::setDateDebut()
,它也不会复制它,而只是链接到它获取的对象参数。
在循环之后你仍然只有两个 DateTime
的实例;其中之一可通过变量 $DateDebut
和循环期间创建的所有 Reservation
对象的成员 $dateDebut
访问。另一个实例是 $DateFin
,同样的讨论也适用于它。
您的代码是 variables aliasing 的受害者。
如何修复:
您需要在循环代码(并将副本传递给 Reservation::setDateDebut()
)或 Reservation::setDateDebut()
:[=35= 的主体中的某处创建 $DateDebut
的副本]
// Either
$res->setDateDebut(clone $DateDebut->add(new \DateInterval('P1D')));
// Or
public function setDateDebut(DateTime $dateDebut)
{
$this->dateDebut = clone $dateDebut;
}
您决定最合适的位置,具体取决于其余代码如何处理这些对象。
因为您在循环中更改了 $DateDebut
的值,所以您应该在那里复制该对象。
如果 class Reservation
更改其 $dateDebut
成员的值,那么您应该(也)在 setter 方法中克隆它。这是因为 Reservation::setDateDebut()
的调用者不希望 Reservation
class 对其作为参数传递的值进行更改。
我对 php 变量有疑问。我使用的代码如下所示:
for($i = 0; $i <= $nbRecurrence; $i++) {
$res = new Reservation();
$res->setDateDebut($DateDebut->add(new \DateInterval('P1D')));
$res->setDateFin($DateFin->add(new \DateInterval('P1D')));
$lesRes[] = $res;
$this->app['orm.ems']['gestionReservationAuto']->persist($res);
$this->app['orm.ems']['gestionReservationAuto']->flush();
}
问题是,虽然我把数组中的每一个元素都加进去了,但是当我用一个var_dump
进行分析时,$lesRes
中的所有$res
都是相同的。数据库中注册的数据还不同...
我怎样才能拥有一个 $res
不喜欢的数组?
(如果我请求将我刚刚添加到数据库中的项目,我有同样的问题,我有一个 x 元素数组 $res
,它们都是相同的。)
我猜 $DateDebut
是一个 DateTime
对象。
我也猜 Reservation::setDateDebut()
看起来像:
class Reservation
{
private $dateDebut;
public function setDateDebut(DateTime $dateDebut)
{
$this->dateDebut = $dateDebut;
}
}
让我们再次编写使用它的代码:
$res = new Reservation();
$res->setDateDebut($DateDebut->add(new \DateInterval('P1D')));
您错过的是 DateTime::add()
不会创建新的 DateTime
对象,而是 returns 对当前对象的引用(即 return $this;
)。
这意味着在每次迭代中,您更改对象 $DateDebut
的值,然后将其传递给 Reservation::setDateDebut()
,它也不会复制它,而只是链接到它获取的对象参数。
在循环之后你仍然只有两个 DateTime
的实例;其中之一可通过变量 $DateDebut
和循环期间创建的所有 Reservation
对象的成员 $dateDebut
访问。另一个实例是 $DateFin
,同样的讨论也适用于它。
您的代码是 variables aliasing 的受害者。
如何修复:
您需要在循环代码(并将副本传递给 Reservation::setDateDebut()
)或 Reservation::setDateDebut()
:[=35= 的主体中的某处创建 $DateDebut
的副本]
// Either
$res->setDateDebut(clone $DateDebut->add(new \DateInterval('P1D')));
// Or
public function setDateDebut(DateTime $dateDebut)
{
$this->dateDebut = clone $dateDebut;
}
您决定最合适的位置,具体取决于其余代码如何处理这些对象。
因为您在循环中更改了 $DateDebut
的值,所以您应该在那里复制该对象。
如果 class Reservation
更改其 $dateDebut
成员的值,那么您应该(也)在 setter 方法中克隆它。这是因为 Reservation::setDateDebut()
的调用者不希望 Reservation
class 对其作为参数传递的值进行更改。