PHP – Motivi per usare Iterators?

Oggi stavo leggendo il manuale e ho notato i vari iteratori . Per me, sembra che siano tutti in qualche modo inutili; Non vedo un motivo per usarli a less che non si preferisca la loro syntax o non si sappia scrivere una function ricorsiva. Ci sono dei motivi per usare gli iteratori integrati in PHP semplicemente scrivendo un ciclo o facendo un metodo ricorsivo?

Sto solo cercando risposte fattuali, non preferenze soggettive (cioè: non mi interessa se pensi che sia più "leggibile" o "più orientato agli oggetti", voglio sapere se sono più veloci, offrono funzionalità che possono essere raggiunto quando si rotola il proprio, ecc.).

Credo che la ragione principale sia la versatilità. Non rendono le cose più leggibili e puoi realizzare la maggior parte di ciò che fanno gli iteratori con un semplice foreach .

Ma gli iteratori possono essere una specie di loop compatti o di una sorgente loop che è ansible trasmettere. È ansible avere più origini dati diverse dalla semplice list / matrix. E il vero vantaggio è che puoi avvolgerli o impilarli per l'aggregazione.

La denominazione è in qualche modo non ovvia, ma suppongo che si possa usare AppendIterator per combinare ad esempio un elenco statico di nomi di file e il risultato di un DirectoryIterator . In alternativa, avvolgerlo in un LimitIterator invece che LimitIterator in una condizione. Tutte queste sono caratteristiche di base e possono essere eseguite manualmente in un foreach. Ma alless RegexIterator e FilterIterator sembrano adatti a ridurre un po 'di complessità.

Ma alla fine è davvero una scelta stilistica. Avrebbe più senso se si hanno oggetti personalizzati che attraversano qualcosa (ad esempio un object VFS che può puntare a file reali o voci di database). Ma anche in questo caso è ansible convertire iterator_to_arrays un elenco di questo tipo e utilizzare un normale foreach -over-arrays.

L'unico caso in cui è davvero fondamentale preferire gli iteratori se la fonte dei dati è illimitata. Gli arrays dispiegati per l'uso in un foreach possono consumare più memory di un iteratore che può recuperare elemento per elemento.

Il vantaggio principale degli iteratori è che astraggono il concetto di iterazione. Ciò significa che tutti i fornitori di dati possono essere utilizzati attraverso la stessa interface. E questo è esattamente where puoi approfittarne:

  • Pigrizia
  • Utilizzo della memory ridotto
  • Composizione

Pigrizia

Con i fornitori di dati, i dati vengono recuperati solo quando ne hai effettivamente bisogno (ad esempio quando si itera).

Utilizzo della memory ridotto

Iterator ti incoraggiano a elaborare i dati in modo iterativo, invece di memorizzarli in memory. Mentre è ansible farlo senza gli iteratori, le astrazioni che forniscono nascondono l'implementazione che li rende davvero facili da usare.

Composizione

Cosa disse mario.


Juozas Kaziukėnas ha recentemente scritto un post sul blog su come utilizzare gli iteratori per emulare una valutazione pigra in PHP. Entra nei dettagli di alcune delle cose che ho menzionato.

Un semplice esempio: implementazione di un object a cui è ansible accedere e attraversare come un arrays. SimpleXML è un bell'esempio del potente comportmento che può essere ottenuto con questo.

Per realizzare ciò è ansible implement l' interface Iterator che definisce i methods public current() , public key() , public next() , public rewind() e public valid() .

Oppure puoi semplicemente implement l' interface alternativa IteratorAggregate che definisce un metodo public getIterator() che restituisce semplicemente un Iterator per i dati interni che vuoi esporre.

Assicurati di controllare gli esempi delle interfacce di cui sopra e vedrai il vantaggio.

La domanda può avere una grande varietà di risposte, ma le risposte appropriate probabilmente possono essere riassunte come: Iterator può essere usato per iterare qualcosa di più complesso di un semplice arrays .

Un esempio è un tipo di ORM o generatore di query. Supponiamo di averne uno: utilizzarlo potrebbe sembrare così:

 $friends = new Model_Friend(); $friends = $people->where('age','>',30)->where('gender','=','female'); foreach ($friends as $friend) { echo $friend->name; } 

Gli iteratori sono veloci come qualsiasi altra cosa, ma con un'interface più semplice e forse più verbage da inserire. Tuttavia, il vantaggio principale non è quello di cui potresti aver bisogno in questo momento, ma come puoi estenderli per affrontare i tuoi problemi futuri ( e verranno!), ed è quello che noi vecchi chiamano "salvare il tuo futuro asino". 🙂