PHP:for循环后数组值的更改
我知道标题看起来很奇怪,但这就是我刚刚遇到的情况。PHP:for循环后数组值的更改,php,arrays,Php,Arrays,我知道标题看起来很奇怪,但这就是我刚刚遇到的情况。 我创建了一个函数,它接受DateTime和integer并返回日期的array,这是我的代码: public static function generateAfterDate(\DateTime $from, $number){ $days = array(); array_push($days, $from); for($i = 1; $i <= $number; $i++){
我创建了一个函数,它接受
DateTime
和integer
并返回日期的array
,这是我的代码:public static function generateAfterDate(\DateTime $from, $number){
$days = array();
array_push($days, $from);
for($i = 1; $i <= $number; $i++){
$from = $from->modify('+1 day');
$days[] = $from;
var_dump($days[$i]->format('d/m/Y'));//---The first var_dump
}
foreach ($days as $day){
var_dump($day->format('d/m/Y'));//--The second var_dump
}
die;
return $days;
}
generateAfterDate(new \DateTime(), 7);
第二个给了我这个结果:string(10) "22/10/2017" string(10) "23/10/2017" string(10) "24/10/2017" string(10) "25/10/2017" string(10) "26/10/2017" string(10) "27/10/2017" string(10) "28/10/2017"
string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017" string(10) "28/10/2017"
有人能解释一下吗?之所以会发生这种情况,是因为包含对象的变量(如
DateTime
对象)实际上并不包含该对象,而是对保存该对象的内存地址的引用
因此,通过将$from
变量放入$days
数组,您并不是将DateTime对象及其当前状态的副本放入数组,而是将内存地址引用的副本放入数组。因此,修改$from
引用指向的日期时间也将修改$days
数组中每个条目引用的相同日期时间
相反,您需要做的是在将DateTime对象添加到数组中时,将其复制到新的DateTime实例中。幸运的是,PHP有一种简单的方法可以做到这一点:clone
array_push($days, clone $from);
for($i = 1; $i <= $number; $i++){
$from = $from->modify('+1 day');
$days[] = clone $from;
var_dump($days[$i]->format('d/m/Y'));//---The first var_dump
}
array\u push($days,clone$from);
对于($i=1;$i修改(“+1天”);
$days[]=克隆$from;
变量转储($days[$i]->format('d/m/Y');/——第一个变量转储
}
现在,您的
$days
数组仍将包含对内存地址的引用,但它将是一个不同的内存地址,包含每个条目的DateTime
对象的唯一实例。发生这种情况是因为变量包含对象(如DateTime
对象)实际上并不包含该对象,而是对保存该对象的内存地址的引用
因此,通过将$from
变量放入$days
数组中,您并不是将DateTime对象及其当前状态的副本放入数组中,而是将内存地址引用的副本放入数组中。因此,修改$from
引用指向的日期时间也会修改您的$days
数组中的每个条目都引用了相同的日期时间
相反,您需要做的是在将DateTime对象添加到数组中时将其复制到新的DateTime实例中
array_push($days, clone $from);
for($i = 1; $i <= $number; $i++){
$from = $from->modify('+1 day');
$days[] = clone $from;
var_dump($days[$i]->format('d/m/Y'));//---The first var_dump
}
array\u push($days,clone$from);
对于($i=1;$i修改(“+1天”);
$days[]=克隆$from;
变量转储($days[$i]->format('d/m/Y');/——第一个变量转储
}
现在,您的
$days
数组仍将包含对内存地址的引用,但它将是一个不同的内存地址,包含每个条目的日期时间
对象的唯一实例。因为我认为您的第一个var_转储是正确的,并且具有预期的结果,第二个仅返回最后一个值,因为ch loop在使用变量$day时创建数组的副本,以便它始终引用正确代码所在的最后一个变量
foreach ($days as $key=>$day){
var_dump($days[$key]->format('d/m/Y'));//--The second var_dump
}
因为我认为您的第一个var_转储是正确的,并且具有预期的结果,所以第二个只返回最后一个值,因为foreach循环在您使用变量$day时创建数组的副本,所以它将始终引用最后一个值。正确的代码是
foreach ($days as $key=>$day){
var_dump($days[$key]->format('d/m/Y'));//--The second var_dump
}