diff --git a/language/attributes.xml b/language/attributes.xml
new file mode 100644
index 00000000..8e599053
--- /dev/null
+++ b/language/attributes.xml
@@ -0,0 +1,389 @@
+
+
+
+ Attributi
+
+ Panoramica sugli attributi
+
+
+
+ Gli attributi PHP forniscono metadati strutturati e leggibili dalla macchina per classi, metodi,
+ funzioni, parametri, proprietà e costanti. Possono essere ispezionati a runtime
+ tramite la Reflection API, abilitando un comportamento
+ dinamico senza modificare il codice. Gli attributi forniscono un modo dichiarativo per annotare
+ il codice con metadati.
+
+
+ Gli attributi permettono di disaccoppiare l'implementazione di una funzionalità dal suo utilizzo. Mentre
+ le interfacce definiscono la struttura imponendo metodi, gli attributi forniscono metadati su più
+ elementi, inclusi metodi, funzioni, proprietà e costanti. A differenza delle interfacce,
+ che impongono l'implementazione dei metodi, gli attributi annotano il codice senza alterarne la struttura.
+
+
+ Gli attributi possono completare o sostituire i metodi opzionali delle interfacce fornendo metadati invece di
+ una struttura imposta. Si consideri un'interfaccia ActionHandler che rappresenta
+ un'operazione in un'applicazione. Alcune implementazioni possono richiedere un passo di configurazione mentre altre no.
+ Invece di forzare tutte le classi che implementano ActionHandler a definire un
+ metodo setUp(), un attributo può indicare i requisiti di configurazione. Questo approccio
+ aumenta la flessibilità, permettendo di applicare gli attributi più volte quando necessario.
+
+
+
+ Implementazione di metodi opzionali di un'interfaccia con gli Attributi
+
+fileName)) {
+ throw new RuntimeException("File does not exist");
+ }
+ }
+
+ #[SetUp]
+ public function targetDirectoryExists()
+ {
+ if (!file_exists($this->targetDirectory)) {
+ mkdir($this->targetDirectory);
+ } elseif (!is_dir($this->targetDirectory)) {
+ throw new RuntimeException("Target directory $this->targetDirectory is not a directory");
+ }
+ }
+
+ public function execute()
+ {
+ copy($this->fileName, $this->targetDirectory . '/' . basename($this->fileName));
+ }
+}
+
+function executeAction(ActionHandler $actionHandler)
+{
+ $reflection = new ReflectionObject($actionHandler);
+
+ foreach ($reflection->getMethods() as $method) {
+ $attributes = $method->getAttributes(SetUp::class);
+
+ if (count($attributes) > 0) {
+ $methodName = $method->getName();
+
+ $actionHandler->$methodName();
+ }
+ }
+
+ $actionHandler->execute();
+}
+
+$copyAction = new CopyFile();
+$copyAction->fileName = "/tmp/foo.jpg";
+$copyAction->targetDirectory = "/home/user";
+
+executeAction($copyAction);
+]]>
+
+
+
+
+
+ Sintassi degli attributi
+
+
+ La sintassi degli attributi è composta da diversi elementi chiave. Una dichiarazione
+ di attributo inizia con #[ e termina con
+ ]. All'interno, è possibile elencare uno o più attributi,
+ separati da virgole. Il nome dell'attributo può essere non qualificato, qualificato
+ o completamente qualificato, come descritto in Utilizzo base dei Namespace.
+ Gli argomenti dell'attributo sono opzionali e racchiusi tra parentesi
+ (). Gli argomenti possono essere solo valori letterali o espressioni
+ costanti. È supportata sia la sintassi con argomenti posizionali che quella con argomenti nominati.
+
+
+
+ I nomi degli attributi e i loro argomenti vengono risolti in una classe, e gli argomenti
+ vengono passati al suo costruttore quando un'istanza dell'attributo viene richiesta
+ tramite la Reflection API. Pertanto, è raccomandato introdurre una classe
+ per ogni attributo.
+
+
+
+ Sintassi degli Attributi
+
+
+value = $value;
+ }
+}
+
+// b.php
+
+namespace Another;
+
+use MyExample\MyAttribute;
+
+#[MyAttribute]
+#[\MyExample\MyAttribute]
+#[MyAttribute(1234)]
+#[MyAttribute(value: 1234)]
+#[MyAttribute(MyAttribute::VALUE)]
+#[MyAttribute(array("key" => "value"))]
+#[MyAttribute(100 + 200)]
+class Thing
+{
+}
+
+#[MyAttribute(1234), MyAttribute(5678)]
+class AnotherThing
+{
+}
+]]>
+
+
+
+
+
+
+ Leggere gli attributi con la Reflection API
+
+
+ Per accedere agli attributi da classi, metodi, funzioni, parametri, proprietà
+ e costanti di classe, si utilizza il metodo getAttributes fornito
+ dalla Reflection API. Questo metodo restituisce un array di istanze di ReflectionAttribute.
+ Queste istanze possono essere interrogate per ottenere il nome dell'attributo, gli argomenti, e
+ possono essere utilizzate per creare un'istanza dell'attributo rappresentato.
+
+
+
+ Separare la rappresentazione riflessa dell'attributo dalla sua istanza effettiva fornisce un maggiore
+ controllo sulla gestione degli errori, come classi di attributi mancanti, argomenti errati
+ o valori mancanti. Gli oggetti della classe attributo vengono istanziati solo dopo la chiamata a
+ ReflectionAttribute::newInstance, garantendo che la validazione degli argomenti
+ avvenga in quel momento.
+
+
+
+ Lettura degli attributi utilizzando la Reflection API
+
+
+value = $value;
+ }
+}
+
+#[MyAttribute(value: 1234)]
+class Thing
+{
+}
+
+function dumpAttributeData($reflection) {
+ $attributes = $reflection->getAttributes();
+
+ foreach ($attributes as $attribute) {
+ var_dump($attribute->getName());
+ var_dump($attribute->getArguments());
+ var_dump($attribute->newInstance());
+ }
+}
+
+dumpAttributeData(new ReflectionClass(Thing::class));
+/*
+string(11) "MyAttribute"
+array(1) {
+ ["value"]=>
+ int(1234)
+}
+object(MyAttribute)#3 (1) {
+ ["value"]=>
+ int(1234)
+}
+*/
+
+]]>
+
+
+
+
+ Invece di iterare su tutti gli attributi dell'istanza di riflessione,
+ è possibile recuperare solo quelli di una specifica classe di attributo passando
+ il nome della classe attributo come argomento.
+
+
+
+ Lettura di attributi specifici utilizzando la Reflection API
+
+
+getAttributes(MyAttribute::class);
+
+ foreach ($attributes as $attribute) {
+ var_dump($attribute->getName());
+ var_dump($attribute->getArguments());
+ var_dump($attribute->newInstance());
+ }
+}
+
+dumpMyAttributeData(new ReflectionClass(Thing::class));
+]]>
+
+
+
+
+
+ Dichiarazione delle classi attributo
+
+
+ È raccomandato definire una classe separata per ogni attributo. Nel caso più semplice,
+ è sufficiente una classe vuota con la dichiarazione #[Attribute].
+ L'attributo può essere importato dal namespace globale utilizzando un'istruzione
+ use.
+
+
+
+ Classe attributo semplice
+
+
+
+
+
+
+
+ Per limitare i tipi di dichiarazioni a cui un attributo può essere applicato,
+ è possibile passare una bitmask come primo argomento alla dichiarazione
+ #[Attribute].
+
+
+
+ Utilizzo della specifica del target per limitare dove gli attributi possono essere usati
+
+
+
+
+
+
+ Dichiarare MyAttribute su un altro tipo genererà ora un'eccezione durante
+ la chiamata a ReflectionAttribute::newInstance
+
+
+
+ È possibile specificare i seguenti target:
+
+
+ Attribute::TARGET_CLASS
+ Attribute::TARGET_FUNCTION
+ Attribute::TARGET_METHOD
+ Attribute::TARGET_PROPERTY
+ Attribute::TARGET_CLASS_CONSTANT
+ Attribute::TARGET_PARAMETER
+ Attribute::TARGET_ALL
+
+
+
+ Per impostazione predefinita, un attributo può essere utilizzato solo una volta per dichiarazione. Per
+ permettere a un attributo di essere ripetibile, è necessario specificarlo nella bitmask della
+ dichiarazione #[Attribute] utilizzando il flag
+ Attribute::IS_REPEATABLE.
+
+
+
+ Utilizzo di IS_REPEATABLE per permettere un attributo su una dichiarazione più volte
+
+
+
+
+
+
+
+
+
+
diff --git a/language/expressions.xml b/language/expressions.xml
new file mode 100644
index 00000000..efa1aa31
--- /dev/null
+++ b/language/expressions.xml
@@ -0,0 +1,237 @@
+
+
+
+ Espressioni
+
+ Le espressioni sono i blocchi costruttivi più importanti di PHP. In PHP,
+ quasi tutto ciò che si scrive è un'espressione. Il modo più semplice e al
+ tempo stesso più accurato per definire un'espressione è "tutto ciò che ha un
+ valore".
+
+
+ Le forme più basilari di espressioni sono le costanti e le variabili.
+ Quando si scrive $a = 5, si assegna 5 a
+ $a. 5, ovviamente,
+ ha il valore 5, o in altre parole 5 è un'espressione con il
+ valore 5 (in questo caso, 5 è una costante intera).
+
+
+ Dopo questa assegnazione, ci si aspetta che il valore di $a sia 5,
+ quindi scrivendo $b = $a, ci si aspetta che si comporti come
+ se si fosse scritto $b = 5. In altre parole, $a è un'espressione con il
+ valore 5 anch'essa. Se tutto funziona correttamente, è esattamente
+ ciò che accadrà.
+
+
+ Esempi leggermente più complessi di espressioni sono le funzioni. Per
+ esempio, si consideri la seguente funzione:
+
+
+
+]]>
+
+
+
+
+ Presupponendo familiarità con il concetto di funzioni (in caso contrario,
+ si consulti il capitolo sulle funzioni), si presume
+ che scrivere $c = foo() sia essenzialmente come
+ scrivere $c = 5, e questo è corretto. Le funzioni
+ sono espressioni con il valore del loro valore di ritorno. Poiché foo()
+ restituisce 5, il valore dell'espressione 'foo()' è 5. Di solito
+ le funzioni non restituiscono semplicemente un valore statico ma calcolano qualcosa.
+
+
+ Naturalmente, i valori in PHP non devono necessariamente essere interi, e molto spesso
+ non lo sono. PHP supporta quattro tipi di valori scalari: valori int,
+ valori a virgola mobile (float), valori string
+ e valori bool (i valori scalari sono valori che non possono
+ essere "suddivisi" in parti più piccole, a differenza degli array, per esempio). PHP supporta anche
+ due tipi compositi (non scalari): array e oggetti. Ciascuno di
+ questi tipi di valore può essere assegnato a variabili o restituito da funzioni.
+
+
+ PHP porta le espressioni molto oltre, nello stesso modo in cui lo fanno molti altri linguaggi.
+ PHP è un linguaggio orientato alle espressioni, nel
+ senso che quasi tutto è un'espressione. Si consideri
+ l'esempio già trattato, $a = 5. È facile vedere che
+ ci sono due valori coinvolti, il valore della costante
+ intera 5 e il valore di $a che viene aggiornato a 5
+ anch'esso. Ma la verità è che c'è un valore aggiuntivo coinvolto,
+ ed è il valore dell'assegnazione stessa. L'assegnazione
+ stessa restituisce il valore assegnato, in questo caso 5.
+ In pratica, significa che $a = 5, indipendentemente da ciò che fa,
+ è un'espressione con il valore 5. Pertanto, scrivere qualcosa come
+ $b = ($a = 5) è come scrivere
+ $a = 5; $b = 5; (un punto e virgola
+ segna la fine di un'istruzione). Poiché le assegnazioni sono analizzate da
+ destra a sinistra, è anche possibile scrivere $b = $a = 5.
+
+
+ Un altro buon esempio di orientamento alle espressioni è il pre- e
+ post-incremento e decremento. Gli utenti di PHP e di molti altri
+ linguaggi possono avere familiarità con la notazione variable++ e
+ variable--. Questi sono gli
+ operatori di incremento e decremento. In PHP, come in C, ci
+ sono due tipi di incremento - il pre-incremento e il post-incremento.
+ Sia il pre-incremento che il post-incremento incrementano essenzialmente la
+ variabile, e l'effetto sulla variabile è identico. La
+ differenza sta nel valore dell'espressione di incremento.
+ Il pre-incremento, che si scrive ++$variable, restituisce il
+ valore incrementato (PHP incrementa la variabile prima di leggerne il
+ valore, da cui il nome 'pre-incremento'). Il post-incremento, che si
+ scrive $variable++, restituisce il valore originale di
+ $variable, prima che venga incrementato (PHP incrementa la variabile
+ dopo averne letto il valore, da cui il nome 'post-incremento').
+
+
+ Un tipo molto comune di espressioni sono le espressioni di confronto.
+ Queste espressioni restituiscono &false; o &true;. PHP
+ supporta > (maggiore di), >= (maggiore o uguale a), == (uguale),
+ != (diverso), < (minore di) e <= (minore o uguale a).
+ Il linguaggio supporta anche un insieme di operatori di equivalenza stretta: ===
+ (uguale a e dello stesso tipo) e !== (diverso da o non dello stesso tipo).
+ Queste espressioni sono più comunemente utilizzate all'interno dell'esecuzione condizionale,
+ come le istruzioni if.
+
+
+ L'ultimo esempio di espressioni qui trattato riguarda le espressioni combinate
+ operatore-assegnazione. È già noto che per
+ incrementare $a di 1, è sufficiente scrivere
+ $a++ o ++$a.
+ Ma cosa fare per aggiungere più di uno, per esempio 3?
+ Si potrebbe scrivere $a++ più volte, ma questo
+ non è ovviamente un modo molto efficiente o comodo. Una pratica molto più
+ comune è scrivere $a =
+ $a + 3. $a + 3 restituisce
+ il valore di $a più 3, e viene riassegnato
+ a $a, il che comporta l'incremento di $a
+ di 3. In PHP, come in diversi altri linguaggi come il C, è possibile scriverlo
+ in modo più breve, che con il tempo diventerà più chiaro e rapido da
+ comprendere. Aggiungere 3 al valore corrente di $a
+ può essere scritto $a += 3. Questo significa esattamente
+ "prendi il valore di $a, aggiungi 3, e riassegnalo
+ a $a". Oltre ad essere più breve e
+ più chiaro, questo produce anche un'esecuzione più veloce. Il valore di
+ $a += 3, come il valore di un'assegnazione normale, è
+ il valore assegnato. Da notare che NON è 3, ma il valore combinato
+ di $a più 3 (questo è il valore che viene
+ assegnato a $a). Qualsiasi operatore binario può essere usato
+ in questa modalità operatore-assegnazione, per esempio $a -= 5
+ (sottrae 5 dal valore di $a), $b *= 7
+ (moltiplica il valore di $b per 7), ecc.
+
+
+ C'è un'altra espressione che può sembrare strana se non è stata incontrata
+ in altri linguaggi, l'operatore condizionale ternario:
+
+
+
+
+
+]]>
+
+
+
+
+ Se il valore della prima sottoespressione è &true; (diverso da zero), allora
+ la seconda sottoespressione viene valutata, e quello è il risultato
+ dell'espressione condizionale. Altrimenti, la terza sottoespressione viene
+ valutata, e quello è il valore.
+
+
+ Il seguente esempio dovrebbe aiutare a comprendere meglio il pre- e
+ post-incremento e le espressioni in generale:
+
+
+
+
+
+]]>
+
+
+
+
+ Alcune espressioni possono essere considerate come istruzioni. In
+ questo caso, un'istruzione ha la forma 'expr ;' cioè, un'espressione
+ seguita da un punto e virgola. In $b = $a = 5;,
+ $a = 5 è un'espressione valida, ma non è un'istruzione
+ di per sé. $b = $a = 5;, invece, è un'istruzione valida.
+
+
+ Un'ultima cosa degna di nota è il valore di verità delle espressioni.
+ In molte situazioni, principalmente nell'esecuzione condizionale e nei cicli, non
+ interessa il valore specifico dell'espressione, ma solo
+ se significa &true; o &false;.
+
+
+
+ Le costanti &true; e &false; (senza distinzione tra maiuscole e minuscole) sono i due
+ possibili valori booleani. Quando necessario, un'espressione viene
+ automaticamente convertita in booleano. Si consulti la
+ sezione sul
+ type-casting per i dettagli.
+
+
+ PHP fornisce un'implementazione completa e potente delle espressioni, e
+ documentarla interamente va oltre lo scopo di questo manuale. Gli
+ esempi precedenti dovrebbero dare una buona idea di cosa sono le espressioni
+ e di come costruire espressioni utili. Nel resto di questo manuale si scriverà
+ expr per indicare qualsiasi espressione PHP valida.
+
+
+
+
diff --git a/language/generators.xml b/language/generators.xml
new file mode 100644
index 00000000..0972f26c
--- /dev/null
+++ b/language/generators.xml
@@ -0,0 +1,605 @@
+
+
+
+ Generatori
+
+
+ Panoramica sui generatori
+
+
+
+ I generatori forniscono un modo semplice per implementare
+ iteratori semplici senza il
+ sovraccarico o la complessità dell'implementazione di una classe che implementa
+ l'interfaccia Iterator.
+
+
+
+ Un generatore offre un modo comodo per fornire dati ai cicli &foreach; senza
+ dover costruire un array in memoria in anticipo, il che potrebbe causare il superamento
+ del limite di memoria del programma o richiedere una notevole quantità di
+ tempo di elaborazione per la generazione. È invece possibile utilizzare una funzione generatore,
+ che è identica a una normale
+ funzione, tranne per il fatto che invece di
+ restituire un valore una sola volta, un
+ generatore può eseguire &yield; tutte le volte necessarie per fornire i
+ valori su cui iterare.
+ Come per gli iteratori, l'accesso casuale ai dati non è possibile.
+
+
+
+ Un semplice esempio è la reimplementazione della funzione range
+ come generatore. La funzione standard range
+ deve generare un array con tutti i valori al suo interno e restituirlo, il che può
+ risultare in array di grandi dimensioni: per esempio, la chiamata a
+ range(0, 1000000) comporterà l'utilizzo di ben oltre 100 MB di
+ memoria.
+
+
+
+ In alternativa, è possibile implementare un generatore xrange(),
+ che necessiterà solo di memoria sufficiente per creare un
+ oggetto Iterator e tracciare lo stato corrente del
+ generatore internamente, il che risulta essere meno di 1 kilobyte.
+
+
+
+ Implementazione di range come generatore
+
+= 0) {
+ throw new LogicException('Step must be negative');
+ }
+
+ for ($i = $start; $i >= $limit; $i += $step) {
+ yield $i;
+ }
+ }
+}
+
+/*
+ * Da notare che sia range() che xrange() producono lo stesso
+ * output qui sotto.
+ */
+
+echo 'Single digit odd numbers from range(): ';
+foreach (range(1, 9, 2) as $number) {
+ echo "$number ";
+}
+echo "\n";
+
+echo 'Single digit odd numbers from xrange(): ';
+foreach (xrange(1, 9, 2) as $number) {
+ echo "$number ";
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ Oggetti Generator
+
+ Quando viene chiamata una funzione generatore, viene restituito un nuovo oggetto della
+ classe interna Generator. Questo oggetto
+ implementa l'interfaccia Iterator in modo molto simile
+ a come farebbe un oggetto iteratore unidirezionale, e fornisce metodi che possono
+ essere chiamati per manipolare lo stato del generatore, incluso l'invio
+ di valori e la restituzione di valori da esso.
+
+
+
+
+
+ Sintassi dei generatori
+
+
+ Una funzione generatore ha esattamente lo stesso aspetto di una funzione normale, tranne per il fatto che invece
+ di restituire un valore, un generatore esegue &yield; di tutti i valori necessari.
+ Qualsiasi funzione che contiene &yield; è una funzione generatore.
+
+
+
+ Quando viene chiamata una funzione generatore, restituisce un oggetto su cui è possibile
+ iterare. Quando si itera su quell'oggetto (per esempio, tramite un
+ ciclo &foreach;), PHP chiama i metodi di iterazione dell'oggetto ogni volta che ha bisogno di un
+ valore, poi salva lo stato del generatore quando il generatore produce un
+ valore in modo che possa essere ripreso quando il valore successivo è richiesto.
+
+
+
+ Una volta che non ci sono più valori da produrre, il generatore
+ può semplicemente ritornare, e il codice chiamante continua come se un array avesse esaurito
+ i valori.
+
+
+
+
+ Un generatore può restituire valori, che possono essere recuperati utilizzando
+ Generator::getReturn.
+
+
+
+
+ La parola chiave yield
+
+
+ Il cuore di una funzione generatore è la parola chiave yield.
+ Nella sua forma più semplice, un'istruzione yield assomiglia molto a un'istruzione return,
+ tranne per il fatto che invece di interrompere l'esecuzione della funzione e
+ restituire un valore, yield fornisce un valore al codice che itera sul
+ generatore e mette in pausa l'esecuzione della funzione generatore.
+
+
+
+ Un semplice esempio di produzione di valori con yield
+
+
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Internamente, le chiavi intere sequenziali vengono abbinate ai valori prodotti,
+ proprio come con un array non associativo.
+
+
+
+
+ Produzione di valori con chiavi
+
+
+ PHP supporta anche gli array associativi, e i generatori non fanno eccezione. Oltre
+ a produrre valori semplici, come mostrato sopra, è anche possibile produrre
+ una chiave contemporaneamente.
+
+
+
+ La sintassi per produrre una coppia chiave/valore è molto simile a quella utilizzata per
+ definire un array associativo, come mostrato di seguito.
+
+
+
+ Produzione di una coppia chiave/valore
+
+ $fields;
+ }
+}
+
+foreach (input_parser($input) as $id => $fields) {
+ echo "$id:\n";
+ echo " $fields[0]\n";
+ echo " $fields[1]\n";
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Produzione di valori null
+
+
+ Yield può essere chiamato senza argomenti per produrre un valore &null; con una
+ chiave automatica.
+
+
+
+ Produzione di &null;
+
+
+]]>
+
+ &example.outputs;
+
+
+ NULL
+ [1]=>
+ NULL
+ [2]=>
+ NULL
+}
+]]>
+
+
+
+
+
+ Produzione per riferimento
+
+
+ Le funzioni generatore possono produrre valori per riferimento oltre che per
+ valore. Questo avviene nello stesso modo in cui si
+ restituiscono riferimenti dalle funzioni:
+ anteponendo un ampersand al nome della funzione.
+
+
+
+ Produzione di valori per riferimento
+
+ 0) {
+ yield $value;
+ }
+}
+
+/*
+ * Da notare che è possibile modificare $number all'interno del ciclo, e
+ * poiché il generatore produce riferimenti, $value
+ * all'interno di gen_reference() cambia.
+ */
+foreach (gen_reference() as &$number) {
+ echo (--$number).'... ';
+}
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Delega dei generatori tramite yield from
+
+
+ La delega dei generatori permette di produrre valori da un altro
+ generatore, da un oggetto Traversable, o da un
+ array utilizzando la parola chiave yield from.
+ Il generatore esterno produrrà quindi tutti i valori del generatore interno,
+ dell'oggetto o dell'array fino a quando non saranno più validi, dopodiché l'esecuzione
+ continuerà nel generatore esterno.
+
+
+
+ Se un generatore viene utilizzato con yield from, l'espressione
+ yield from restituirà anche qualsiasi valore
+ restituito dal generatore interno.
+
+
+
+ Memorizzazione in un array (es. con iterator_to_array)
+
+
+ yield from non reimposta le chiavi. Preserva
+ le chiavi restituite dall'oggetto Traversable o dall'
+ array. Pertanto alcuni valori possono condividere una chiave comune con un altro
+ yield o yield from, che, all'inserimento
+ in un array, sovrascriverà i valori precedenti con quella chiave.
+
+
+
+ Un caso comune in cui questo è rilevante è iterator_to_array
+ che restituisce per impostazione predefinita un array con chiavi, portando a risultati
+ potenzialmente inaspettati.
+ iterator_to_array ha un secondo parametro
+ preserve_keys che può essere impostato a &false; per raccogliere
+ tutti i valori ignorando le chiavi restituite dal Generator.
+
+
+
+ yield from con iterator_to_array
+
+
+]]>
+
+ &example.outputs;
+
+
+ int(1)
+ [1]=>
+ int(4)
+ [2]=>
+ int(3)
+}
+]]>
+
+
+
+
+
+ Utilizzo base di yield from
+
+
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ yield from e valori di ritorno
+
+getReturn();
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+
+
+ Confronto tra generatori e oggetti Iterator
+
+
+ Il vantaggio principale dei generatori è la loro semplicità. È necessario scrivere molto meno
+ codice boilerplate rispetto all'implementazione di una classe
+ Iterator, e il codice è generalmente molto più
+ leggibile. Per esempio, la seguente funzione e classe sono equivalenti:
+
+
+
+
+fileHandle = fopen($fileName, 'r')) {
+ throw new RuntimeException('Couldn\'t open file "' . $fileName . '"');
+ }
+ }
+
+ public function rewind() {
+ fseek($this->fileHandle, 0);
+ $this->line = fgets($this->fileHandle);
+ $this->i = 0;
+ }
+
+ public function valid() {
+ return false !== $this->line;
+ }
+
+ public function current() {
+ return $this->line;
+ }
+
+ public function key() {
+ return $this->i;
+ }
+
+ public function next() {
+ if (false !== $this->line) {
+ $this->line = fgets($this->fileHandle);
+ $this->i++;
+ }
+ }
+
+ public function __destruct() {
+ fclose($this->fileHandle);
+ }
+}
+?>
+]]>
+
+
+
+
+ Questa flessibilità ha tuttavia un costo: i generatori sono iteratori unidirezionali
+ e non possono essere riavvolti una volta che l'iterazione è iniziata. Questo significa
+ anche che lo stesso generatore non può essere iterato più volte: il
+ generatore dovrà essere ricostruito chiamando nuovamente la funzione generatore.
+
+
+
+ &reftitle.seealso;
+
+
+ Iterazione sugli oggetti
+
+
+
+
+
+
+
+