From d48e439c97333638f359b1e4ce788c0926061061 Mon Sep 17 00:00:00 2001 From: lacatoire Date: Thu, 26 Feb 2026 18:16:31 +0100 Subject: [PATCH] Add Italian translation for attributes, expressions and generators --- language/attributes.xml | 389 +++++++++++++++++++++++++ language/expressions.xml | 237 +++++++++++++++ language/generators.xml | 605 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1231 insertions(+) create mode 100644 language/attributes.xml create mode 100644 language/expressions.xml create mode 100644 language/generators.xml 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 <function>range</function> 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 <classname>Generator</classname> + + 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 <command>yield</command> + + + 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 <command>yield from</command> + + + 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 <function>iterator_to_array</function>) + + + 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. + + + + <command>yield from</command> con <function>iterator_to_array</function> + + +]]> + + &example.outputs; + + + int(1) + [1]=> + int(4) + [2]=> + int(3) +} +]]> + + + + + + Utilizzo base di <command>yield from</command> + + +]]> + + &example.outputs; + + + + + + + <command>yield from</command> e valori di ritorno + +getReturn(); +?> +]]> + + &example.outputs; + + + + + + + + + + Confronto tra generatori e oggetti <classname>Iterator</classname> + + + 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 + + + + + + + +