2009-09-15 6 views
7

DatePeriod ist eine PHP-Klasse für wiederkehrende Daten. Es hat eine sehr begrenzte Anzahl von Methoden. Wenn ich also grundlegende Array-Funktionen mit den wiederkehrenden Daten ausführen möchte, muss ich es in ein Array mit iterator_to_array kopieren. Seltsamerweise scheint es zu kopieren, es zu kopieren. Irgendwelche Ideen warum?iterator_to_array

$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 
+0

leider einen zwei Jahre alten Post zu stoßen, aber haben Sie es geschafft, um herauszufinden, warum dies geschieht? – calumbrodie

Antwort

3

Hier ist, was ich tun würde. Ich würde verlängern DatePeriod und Umsetzung einer toArray Methode:

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 
+0

Ich verstehe nicht, warum Iterator_to_array ($ this) aus der Klasse nicht das gleiche wie Iterator_to_array ($ p) von außen. Aber ich bin froh, dass es das tut! Vielen Dank. – dnagirl

+1

Es tut das gleiche, aber ich bin das Ergebnis in eine Instanzvariable, "$ Daten", so weiter auf Bei Aufruf von 'toArray' gibt es keine Aufrufe von' iterator_to_array'. Ich habe einfach das zwischengespeicherte Ergebnis zurückgegeben. –

3

Ob vielleicht der Iterator wird durch iterator_to_array() nicht wieder aufgewickelt wird, so dass der zweite Anruf beginnt am Ende mit dem Cursor zu iterieren. Sie könnten versuchen, diese:

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

Wenn der Iterator nicht wiederwickelbarer ist, könnten Sie versuchen, das Objekt klonen, bevor Sie es durchqueren, z.B.

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

$array = iterator_to_array($p); 
+0

Es scheint, dass DatePeriod keine Rückspulmethode hat. :( Die Dokumentation besagt, dass DatePeriod Traversable implementiert. Traversable ist jedoch eine abstrakte Schnittstelle, die die Implementierung von Iterator oder IteratorAggregate erfordert (von denen keine in den DatePeriod-Dokumenten erwähnt wird). IteratorAggregate scheint keine öffentliche Zurückspulmethode zu haben DatePeriod ist ein Kind davon statt Iterator? – dnagirl

+0

Leider ist Klon keine Option.Es scheint einen schwerwiegenden Fehler zu verursachen, aber von welchem ​​Typ ich nicht weiß, da es nicht in den Webprotokollen angezeigt wird .. – dnagirl

+1

As Soweit es mich betrifft, die neuen Datum und Zeit Implementierungen in PHP 5.3 saugen große Zeit. –

2

Vermutlich der erste Anruf durchläuft alle Elemente in der Iterator (d.h. Anrufe next(), bis gültige() ist false). Das vernünftige Verhalten besteht darin, dass iterator_to_array mit der Konvertierung der aktuellen Position im Iterator beginnt - ein stummes Zurückspulen wäre unflexibel und möglicherweise fehlerbehaftet.

Versuchen Sie, den Iterator zurückzuspulen, bevor Sie ihn erneut verwenden.

$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