<?php
function mergeRanges($array){
usort($array,function($a,$b){ return $a['start_date']<=>$b['start_date']; }); // order by start_date ASC
foreach($array as $i=>$row){
if($i && $row['start_date']<=date('Y-m-d',strtotime("{$result[$x]['end_date']} +1 day"))){ // not the first iteration and dates are within current group's range
if($row['end_date']>$result[$x]['end_date']){ // only if current end_date is greater than existing end_date
$result[$x]['end_date']=$row['end_date']; // overwrite end_date with new end_date in group
}
$result[$x]['merged_ids'][]=$row['id']; // append id to merged_ids subarray
}else{ // first iteration or out of range; start new group
if($i){ // if not first iteration
$result[$x]['merged_ids']=implode(', ',$result[$x]['merged_ids']); // convert previous group's id elements to csv string
}else{ // first iteration
$x=-1; // declare $x as -1 so that it becomes 0 when incremented with ++$x
}
$result[++$x]=['merged_ids'=>[$row['id']],'start_date'=>$row['start_date'],'end_date'=>$row['end_date']]; // declare new group
}
}
$result[$x]['merged_ids']=implode(', ',$result[$x]['merged_ids']); // convert final merged_ids subarray to csv string
return $result;
}
$array=[
['id'=>18298,'start_date'=>'2011-07-09','end_date'=>'2011-10-01'],
['id'=>18297,'start_date'=>'2011-06-01','end_date'=>'2011-06-30'],
['id'=>17113,'start_date'=>'2011-03-31','end_date'=>'2011-05-31'], // tests that 17113 and 18297 belong in same group
['id'=>20556,'start_date'=>'2011-02-03','end_date'=>'2011-02-13'], // tests that "fully overlapped" date range is included
['id'=>20555,'start_date'=>'2011-01-03','end_date'=>'2011-03-31']
];
var_export(mergeRanges($array));