[英]PHP — usort is modifying contents of objects in array, how do I prevent this?
我使用usort和用户比较函数来对对象数组进行排序。 在对这些对象的数组运行usort之后,我发现对象的某些值随着它们在数组中的位置而发生了变化。 我错过了什么? 我不相信我的用户比较功能有任何副作用。 我们是如何解构/重建对象的?
这是我正在使用的用户比较功能:
private function SortArrayOfSegments($segments){
foreach($segments as $segment){
echo '<pre>';
var_dump($segment);
}
usort($segments, "AirObject::CompareSegments");
foreach($segments as $segment){
var_dump($segment);
echo '</pre>';
}
return $segments;
}
public static function CompareSegments($a, $b){
$interval = date_diff(date_create($a->StartDateTime->GetString()),
date_create($b->StartDateTime->GetString()));
if($interval->invert == 1){
return 1;
}else if($interval->y == 0 && $interval->m == 0 && $interval->d == 0
&& $interval->i == 0 && $interval->s == 0 && $interval->h == 0){
return 0;
}else if($interval->invert == 0){
return -1;
}
}
我正在使用的对象如下所示:
object(AirSegment)#14 (12) {
["StartDateTime"]=>
object(VDateTime)#27 (4) {
["date"]=>
string(10) "2010-12-07"
["time"]=>
string(8) "09:23:21"
["timezone"]=>
string(0) ""
["utc_offset"]=>
string(0) ""
}
["EndDateTime"]=>
object(VDateTime)#23 (4) {
["date"]=>
string(10) "2010-12-07"
["time"]=>
string(8) "13:23:21"
["timezone"]=>
string(0) ""
["utc_offset"]=>
string(0) ""
}
["start_airport_code"]=>
string(3) "SFO"
["start_city_name"]=>
string(13) "San Francisco"
["end_airport_code"]=>
string(3) "STL"
["end_city_name"]=>
string(8) "St Louis"
["operating_airline"]=>
string(15) "United Airlines"
["operating_flight_number"]=>
string(3) "335"
["duration"]=>
float(NAN)
["required_properties":protected]=>
array(9) {
["StartDateTime"]=>
bool(false)
["EndDateTime"]=>
bool(false)
["start_airport_code"]=>
bool(false)
["end_airport_code"]=>
bool(false)
["operating_airline"]=>
bool(false)
["operating_flight_number"]=>
bool(false)
["start_city_name"]=>
bool(false)
["end_city_name"]=>
bool(false)
["service_class"]=>
bool(true)
}
["service_class"]=>
string(5) "Coach"
["trip_id"]=>
string(4) "1621"
}
正在改变的属性是持续时间属性。 在运行usort之前,每个对象都有一个有效的浮点值。 在用完之后,其中两个是NaN。
解析度:
date_diff有副作用 - 至少在我的PHP构建中。 删除它完全解决了问题。
public static function CompareSegments($a, $b){
$adate = new DateTime($a->StartDateTime->GetString());
$bdate = new DateTime($b->StartDateTime->GetString());
$lessThan = $adate < $bdate;
$equal = $adate == $bdate;
$greaterThan = $adate > $bdate;
if($lessThan){
return -1;
}else if($equal){
return 0;
}else{
return 1;
}
}
在我的头顶,我没有看到任何应该修改数组元素本身的内容。
usort()
工作方式是,当它确定元素的新顺序时,它会向数组中添加新元素,这些元素保存原始值,然后删除原始元素,严格来说,数组中的元素都没有传递给函数永远出来,只有它们的副本(虽然作为您传入的相同数组变量的一部分)。
我没有看到任何理由为什么usort
会破坏和重新构造对象,就像你问的那样,但它确实对数组本身做了类似的事情。 据我所知,除非你在比较函数中明确地做了,否则应该改变数组元素的值。
在CompareSegments
方法中,您调用StartDateTime->GetString()
方法。 GetString()
方法是否可能正在修改您的数据?
在应用usort方法或实际上任何方法之前,对象看起来是什么样的? 在不知道对象的原始状态的情况下很难确定,但NaN是传递给usort的函数产生的错误结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.