2009-09-15 3 views
7

DatePeriod è una classe PHP per la gestione di date ricorrenti. Ha un numero molto limitato di metodi. Quindi, quando voglio eseguire le funzioni di base dell'array con le date ricorrenti, devo copiarlo su un array con iterator_to_array. Stranamente, copiarlo sembra rovinarlo. Qualche idea, perché?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

dispiace di urtare un post di due anni, ma hai fatto a scoprire perché questo sta accadendo? – calumbrodie

risposta

3

Ecco cosa farei. Mi piacerebbe estendo DatePeriod e implementare un metodo toArray:

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

Non capisco perché iterator_to_array ($ this) dall'interno della classe non faccia lo stesso di iterator_to_array ($ p) dall'esterno. Ma sono contento che lo sia! Grazie mille – dnagirl

+1

Fa lo stesso, ma sto memorizzando il risultato nella cache in una variabile di istanza, '$ dates', quindi su subseq uent chiama a 'toArray' non ci sono più chiamate a' iterator_to_array'. Ho semplicemente restituito il risultato memorizzato nella cache. –

3

mi domando se forse l'iteratore è non essere riavvolti da iterator_to_array(), quindi la seconda chiamata inizia iterazione con il cursore alla fine. Si potrebbe provare questo:

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

Se l'iteratore non è riavvolgibile, si potrebbe provare la clonazione del oggetto prima di attraversarla, per esempio

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

$array = iterator_to_array($p); 
+0

Sembra che DatePeriod non abbia un metodo di riavvolgimento. :( La documentazione dice che DatePeriod implementa Traversable, ma Traversable è un'interfaccia astratta che richiede Iterator o IteratorAggregate da implementare (nessuno dei quali è menzionato nei documenti DatePeriod). IteratorAggregate non sembra avere un metodo di rewind pubblico, quindi forse DatePeriod ne è figlio piuttosto che Iterator? – dnagirl

+0

Purtroppo, clone non è un'opzione. Sembra causare un errore irreversibile, ma di quale tipo non so poiché non viene visualizzato nei log Web. – dnagirl

+1

As Per quanto mi riguarda, le nuove implementazioni di data e ora in PHP 5.3 fanno schifo. –

2

Presumibilmente, la prima chiamata attraversa tutti gli elementi della iteratore (cioè chiamate in avanti() fino valido() è falso). Il comportamento sensato è che iterator_to_array inizi la conversione dalla posizione corrente nell'iteratore, il riavvolgimento silenzioso non sarebbe flessibile e potrebbe causare errori.

Provare a riavvolgere l'iteratore prima di riutilizzarlo.

$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