Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iterator_to_array

DatePeriod is a PHP class for handling recurring dates. It has a very limited number of methods. So when I want to do basic array functions with the recurring dates, I have to copy it to an array with iterator_to_array. Strangely, copying it seems to clobber it. Any ideas why?

$p=new DatePeriod(date_create('2008-01-01'),
                  DateInterval::createFromDateString( "+2 days" ),
                  date_create('2008-12-31')); 

echo count(iterator_to_array($p)); //183 

$a=iterator_to_array($p); 
echo count($a); //0 
like image 879
dnagirl Avatar asked Sep 15 '09 13:09

dnagirl


3 Answers

Here's what I'd do. I'd extend DatePeriod and implement a toArray method:

class MyDatePeriod extends DatePeriod
{
    public $dates;

    public function toArray()
    {
        if ($this->dates === null) {
            $this->dates = iterator_to_array($this);
        }

        return $this->dates;
    }
}

$p = new MyDatePeriod(date_create('2008-01-01'),
                      DateInterval::createFromDateString( "+2 days" ),
                      date_create('2008-12-31'));

echo count($p->toArray()) . "\n"; // 183

echo count($p->toArray()) . "\n"; // 183
like image 154
Ionuț G. Stan Avatar answered Oct 09 '22 19:10

Ionuț G. Stan


I wonder if maybe the iterator isn't being re-wound by iterator_to_array(), so the second call starts iterating with the cursor at the end. You could try this:

$p->rewind()
$a=iterator_to_array($p); 

If the iterator is not rewindable, you could try cloning the object before you traverse it, e.g.

$p2 = clone $p;
echo count(iterator_to_array($p2));

$array = iterator_to_array($p);
like image 41
Tom Haigh Avatar answered Oct 09 '22 19:10

Tom Haigh


Presumably, the first call traverses all the elements in the iterator (i.e. calls next() until valid() is false). The sensible behaviour is for iterator_to_array to begin the conversion from the current position in the iterator - having it silently rewind would be inflexible, and possibly bug inducing.

Try rewinding the iterator before using it again.

$p=new DatePeriod(date_create('2008-01-01'),
                  DateInterval::createFromDateString( "+2 days" ),
                  date_create('2008-12-31')); 

echo count(iterator_to_array($p)); //183 

$p->rewind(); // Newly added!

$a=iterator_to_array($p); 
echo count($a); //0
like image 26
Adam Wright Avatar answered Oct 09 '22 20:10

Adam Wright