From 8821de2e2705451cdca69d5269f363a22c1645e9 Mon Sep 17 00:00:00 2001 From: lacatoire Date: Thu, 26 Feb 2026 18:05:29 +0100 Subject: [PATCH] Add Italian translation for OOP traits, magic methods and overloading --- language/oop5/magic.xml | 631 ++++++++++++++++++++++++++++++ language/oop5/overloading.xml | 335 ++++++++++++++++ language/oop5/traits.xml | 711 ++++++++++++++++++++++++++++++++++ 3 files changed, 1677 insertions(+) create mode 100644 language/oop5/magic.xml create mode 100644 language/oop5/overloading.xml create mode 100644 language/oop5/traits.xml diff --git a/language/oop5/magic.xml b/language/oop5/magic.xml new file mode 100644 index 000000000..a8a5ee699 --- /dev/null +++ b/language/oop5/magic.xml @@ -0,0 +1,631 @@ + + + + Metodi magici + + I metodi magici sono metodi speciali che sovrascrivono l'azione predefinita + di PHP quando vengono eseguite determinate azioni su un oggetto. + + + + Tutti i nomi di metodi che iniziano con __ sono riservati + da PHP. Pertanto, non è consigliato usare tali nomi di metodi a meno che + non si voglia sovrascrivere il comportamento di PHP. + + + + I seguenti nomi di metodi sono considerati magici: + + __construct(), + __destruct(), + __call(), + __callStatic(), + __get(), + __set(), + __isset(), + __unset(), + __sleep(), + __wakeup(), + __serialize(), + __unserialize(), + __toString(), + __invoke(), + __set_state(), + __clone() e + __debugInfo(). + + + + + + Tutti i metodi magici, ad eccezione di + __construct(), + __destruct() e + __clone(), + devono essere dichiarati come public, + altrimenti viene emesso un E_WARNING. + Prima di PHP 8.0.0, non veniva emessa alcuna diagnostica per i metodi magici + __sleep(), + __wakeup(), + __serialize(), + __unserialize() e + __set_state(). + + + + + Se vengono usate dichiarazioni di tipo nella definizione di un metodo + magico, queste devono essere identiche alla firma descritta in questo + documento. Altrimenti, viene emesso un errore fatale. + Prima di PHP 8.0.0, non veniva emessa alcuna diagnostica. + Tuttavia, __construct() e + __destruct() non devono dichiarare + un tipo di ritorno; altrimenti viene emesso un errore fatale. + + + + + + <link linkend="object.sleep">__sleep()</link> e + <link linkend="object.wakeup">__wakeup()</link> + + + + public array__sleep + + + + public void__wakeup + + + + + serialize verifica se la classe ha una funzione con + il nome magico __sleep(). In tal caso, + quella funzione viene eseguita prima di qualsiasi serializzazione. Può + ripulire l'oggetto e deve restituire un array con i nomi di tutte le + variabili di quell'oggetto che devono essere serializzate. + Se il metodo non restituisce nulla, viene serializzato &null; e viene + emesso un E_NOTICE. + + + + Non è possibile per __sleep() + restituire nomi di proprietà private nelle classi genitore. Farlo + produrrà un errore di livello E_NOTICE. + Usare __serialize() al suo posto. + + + + + A partire da PHP 8.0.0, la restituzione di un valore che non è un array + da __sleep() genera un avviso. + In precedenza, generava una notifica. + + + + L'uso previsto di __sleep() è quello di + salvare i dati in sospeso o eseguire operazioni di pulizia simili. Inoltre, + la funzione è utile se un oggetto molto grande non ha bisogno di essere + salvato completamente. + + + Al contrario, unserialize verifica la presenza di una + funzione con il nome magico + __wakeup(). Se presente, questa + funzione può ricostruire qualsiasi risorsa che l'oggetto potrebbe avere. + + + L'uso previsto di __wakeup() è quello + di ristabilire qualsiasi connessione al database che potrebbe essere stata + persa durante la serializzazione e di eseguire altre operazioni di + reinizializzazione. + + + Sleep e wakeup + +dsn = $dsn; + $this->username = $username; + $this->password = $password; + $this->connect(); + } + + private function connect() + { + $this->link = new PDO($this->dsn, $this->username, $this->password); + } + + public function __sleep() + { + return array('dsn', 'username', 'password'); + } + + public function __wakeup() + { + $this->connect(); + } +}?> +]]> + + + + + + + <link linkend="object.serialize">__serialize()</link> e + <link linkend="object.unserialize">__unserialize()</link> + + + + public array__serialize + + + + public void__unserialize + arraydata + + + + serialize verifica se la classe ha una funzione con + il nome magico __serialize(). In + tal caso, quella funzione viene eseguita prima di qualsiasi + serializzazione. Deve costruire e restituire un array associativo di coppie + chiave/valore che rappresentano la forma serializzata dell'oggetto. Se non + viene restituito alcun array, verrà lanciato un + TypeError. + + + + Se sia __serialize() che + __sleep() sono definiti nello stesso + oggetto, solo __serialize() verrà + chiamato. __sleep() verrà ignorato. Se + l'oggetto implementa l'interfaccia + Serializable, il metodo + serialize() dell'interfaccia verrà ignorato e verrà + usato __serialize() al suo posto. + + + + L'uso previsto di __serialize() è + quello di definire una rappresentazione arbitraria dell'oggetto adatta alla + serializzazione. Gli elementi dell'array possono corrispondere alle + proprietà dell'oggetto, ma non è obbligatorio. + + + Al contrario, unserialize verifica la presenza di una + funzione con il nome magico + __unserialize(). Se presente, + a questa funzione verrà passato l'array ripristinato che era stato + restituito da __serialize(). Potrà + quindi ripristinare le proprietà dell'oggetto da quell'array come + appropriato. + + + + Se sia __unserialize() che + __wakeup() sono definiti nello stesso + oggetto, solo __unserialize() + verrà chiamato. __wakeup() verrà + ignorato. + + + + + Questa funzionalità è disponibile a partire da PHP 7.4.0. + + + + Serialize e unserialize + +dsn = $dsn; + $this->username = $username; + $this->password = $password; + $this->connect(); + } + + private function connect() + { + $this->link = new PDO($this->dsn, $this->username, $this->password); + } + + public function __serialize(): array + { + return [ + 'dsn' => $this->dsn, + 'user' => $this->username, + 'pass' => $this->password, + ]; + } + + public function __unserialize(array $data): void + { + $this->dsn = $data['dsn']; + $this->username = $data['user']; + $this->password = $data['pass']; + + $this->connect(); + } +}?> +]]> + + + + + + <link linkend="object.tostring">__toString()</link> + + public string__toString + + + + Il metodo __toString() permette a + una classe di decidere come comportarsi quando viene trattata come una + stringa. Ad esempio, cosa stamperà echo $obj;. + + + + A partire da PHP 8.0.0, il valore di ritorno segue la semantica standard + dei tipi PHP, il che significa che verrà convertito in una + string se possibile e se la + tipizzazione stretta + è disabilitata. + + + Un oggetto Stringable + non sarà accettato da una dichiarazione di tipo + string se la + tipizzazione stretta + è abilitata. Se si desidera questo comportamento, la dichiarazione di tipo + deve accettare Stringable e + string tramite un tipo unione. + + + A partire da PHP 8.0.0, qualsiasi classe che contiene un metodo + __toString() implementerà anche + implicitamente l'interfaccia Stringable, e + quindi supererà i controlli di tipo per quell'interfaccia. Si raccomanda + comunque di implementare esplicitamente l'interfaccia. + + + In PHP 7.4, il valore restituito deve essere una + string, altrimenti viene lanciato un + Error. + + + Prima di PHP 7.4.0, il valore restituito deve essere + una string, altrimenti viene emesso un errore fatale + E_RECOVERABLE_ERROR. + + + + + Non era possibile lanciare un'eccezione dall'interno di un metodo + __toString() + prima di PHP 7.4.0. Farlo causava un errore fatale. + + + + Esempio semplice + +foo = $foo; + } + + public function __toString() + { + return $this->foo; + } +} + +$class = new TestClass('Hello'); +echo $class; +?> +]]> + + &example.outputs; + + + + + + + + <link linkend="object.invoke">__invoke()</link> + + mixed__invoke + values + + + Il metodo __invoke() viene chiamato + quando uno script tenta di chiamare un oggetto come una funzione. + + + Utilizzo di <link linkend="object.invoke">__invoke()</link> + + +]]> + + &example.outputs; + + + + + + Utilizzo di <link linkend="object.invoke">__invoke()</link> + +key = $key; + } + + public function __invoke(array $a, array $b): int + { + return $a[$this->key] <=> $b[$this->key]; + } +} + +$customers = [ + ['id' => 1, 'first_name' => 'John', 'last_name' => 'Do'], + ['id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'], + ['id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe'] +]; + +// ordina i clienti per nome +usort($customers, new Sort('first_name')); +print_r($customers); + +// ordina i clienti per cognome +usort($customers, new Sort('last_name')); +print_r($customers); +?> +]]> + + &example.outputs; + + Array + ( + [id] => 3 + [first_name] => Alice + [last_name] => Gustav + ) + + [1] => Array + ( + [id] => 2 + [first_name] => Bob + [last_name] => Filipe + ) + + [2] => Array + ( + [id] => 1 + [first_name] => John + [last_name] => Do + ) + +) +Array +( + [0] => Array + ( + [id] => 1 + [first_name] => John + [last_name] => Do + ) + + [1] => Array + ( + [id] => 2 + [first_name] => Bob + [last_name] => Filipe + ) + + [2] => Array + ( + [id] => 3 + [first_name] => Alice + [last_name] => Gustav + ) + +) +]]> + + + + + + <link linkend="object.set-state">__set_state()</link> + + static object__set_state + arrayproperties + + + Questo metodo statico viene + chiamato per le classi esportate da var_export. + + + L'unico parametro di questo metodo è un array contenente le proprietà + esportate nella forma ['property' => value, ...]. + + + Utilizzo di <link linkend="object.set-state">__set_state()</link> + +var1 = $an_array['var1']; + $obj->var2 = $an_array['var2']; + return $obj; + } +} + +$a = new A; +$a->var1 = 5; +$a->var2 = 'foo'; + +$b = var_export($a, true); +var_dump($b); +eval('$c = ' . $b . ';'); +var_dump($c); +?> +]]> + + &example.outputs; + + 5, + 'var2' => 'foo', +))" +object(A)#2 (2) { + ["var1"]=> + int(5) + ["var2"]=> + string(3) "foo" +} +]]> + + + + + Quando si esporta un oggetto, var_export non verifica + se __set_state() è implementato + dalla classe dell'oggetto, quindi la reimportazione di oggetti risulterà + in un'eccezione Error, se __set_state() non è + implementato. In particolare, questo riguarda alcune classi interne. + + + È responsabilità del programmatore verificare che vengano reimportati solo + oggetti la cui classe implementa __set_state(). + + + + + + <link linkend="object.debuginfo">__debugInfo()</link> + + array__debugInfo + + + + Questo metodo viene chiamato da var_dump durante il + dump di un oggetto per ottenere le proprietà che devono essere mostrate. Se + il metodo non è definito su un oggetto, verranno mostrate tutte le + proprietà pubbliche, protette e private. + + + Utilizzo di <link linkend="object.debuginfo">__debugInfo()</link> + +prop = $val; + } + + public function __debugInfo() { + return [ + 'propSquared' => $this->prop ** 2, + ]; + } +} + +var_dump(new C(42)); +?> +]]> + + &example.outputs; + + + int(1764) +} +]]> + + + + + diff --git a/language/oop5/overloading.xml b/language/oop5/overloading.xml new file mode 100644 index 000000000..859784b39 --- /dev/null +++ b/language/oop5/overloading.xml @@ -0,0 +1,335 @@ + + + + Overloading + + + L'overloading in PHP fornisce i mezzi per + creare dinamicamente proprietà e metodi. + Queste entità dinamiche vengono elaborate tramite metodi magici + che è possibile definire in una classe per vari tipi di azioni. + + + + I metodi di overloading vengono invocati quando si interagisce con + proprietà o metodi che non sono stati dichiarati o che non sono + visibili nello + scope corrente. Il resto di questa sezione userà i termini + proprietà inaccessibili e metodi + inaccessibili per riferirsi a questa combinazione di + dichiarazione e visibilità. + + + + Tutti i metodi di overloading devono essere definiti come + public. + + + + + Nessuno degli argomenti di questi metodi magici può essere + passato per + riferimento. + + + + + + L'interpretazione di PHP dell'overloading è + diversa dalla maggior parte dei linguaggi orientati agli oggetti. + L'overloading tradizionalmente fornisce la possibilità di avere + più metodi con lo stesso nome ma con quantità e tipi di argomenti + differenti. + + + + + Overloading delle proprietà + + + public void__set + stringname + mixedvalue + + + public mixed__get + stringname + + + public bool__isset + stringname + + + public void__unset + stringname + + + + __set() viene eseguito quando si scrivono + dati in proprietà inaccessibili (protette o private) o inesistenti. + + + + __get() viene utilizzato per leggere + dati da proprietà inaccessibili (protette o private) o inesistenti. + + + + __isset() viene attivato chiamando + isset o empty + su proprietà inaccessibili (protette o private) o inesistenti. + + + + __unset() viene invocato quando + unset viene usato su proprietà inaccessibili + (protette o private) o inesistenti. + + + + L'argomento $name è il nome della proprietà con cui + si interagisce. L'argomento $value del metodo + __set() specifica il valore a cui la + proprietà $name deve essere impostata. + + + + L'overloading delle proprietà funziona solo nel contesto dell'oggetto. + Questi metodi magici non verranno attivati nel contesto statico. Pertanto + questi metodi non devono essere dichiarati + static. + Viene emesso un avviso se uno dei metodi magici di overloading + viene dichiarato static. + + + + + Il valore di ritorno di __set() viene + ignorato a causa del modo in cui PHP elabora l'operatore di assegnazione. + Allo stesso modo, __get() non viene mai + chiamato quando si concatenano le assegnazioni in questo modo: + b = 8; ]]> + + + + + + PHP non chiamerà un metodo di overloading dall'interno dello stesso metodo + di overloading. Ciò significa, ad esempio, che scrivere + return $this->foo all'interno di + __get() restituirà null + e genererà un E_WARNING se non esiste una proprietà + foo definita, piuttosto che chiamare + __get() una seconda volta. + Tuttavia, i metodi di overloading possono invocare altri metodi di + overloading implicitamente (come + __set() che attiva + __get()). + + + + + + Overloading delle proprietà tramite i metodi <link linkend="object.get">__get()</link>, + <link linkend="object.set">__set()</link>, <link linkend="object.isset">__isset()</link> + e <link linkend="object.unset">__unset()</link> + + +data[$name] = $value; + } + + public function __get($name) + { + echo "Getting '$name'\n"; + if (array_key_exists($name, $this->data)) { + return $this->data[$name]; + } + + $trace = debug_backtrace(); + trigger_error( + 'Undefined property via __get(): ' . $name . + ' in ' . $trace[0]['file'] . + ' on line ' . $trace[0]['line'], + E_USER_NOTICE); + return null; + } + + public function __isset($name) + { + echo "Is '$name' set?\n"; + return isset($this->data[$name]); + } + + public function __unset($name) + { + echo "Unsetting '$name'\n"; + unset($this->data[$name]); + } + + /** Non è un metodo magico, è qui solo come esempio. */ + public function getHidden() + { + return $this->hidden; + } +} + + +$obj = new PropertyTest; + +$obj->a = 1; +echo $obj->a . "\n\n"; + +var_dump(isset($obj->a)); +unset($obj->a); +var_dump(isset($obj->a)); +echo "\n"; + +echo $obj->declared . "\n\n"; + +echo "Let's experiment with the private property named 'hidden':\n"; +echo "Privates are visible inside the class, so __get() not used...\n"; +echo $obj->getHidden() . "\n"; +echo "Privates not visible outside of class, so __get() is used...\n"; +echo $obj->hidden . "\n"; +?> +]]> + + &example.outputs; + + on line 70 in on line 29 +]]> + + + + + + + Overloading dei metodi + + + public mixed__call + stringname + arrayarguments + + + public static mixed__callStatic + stringname + arrayarguments + + + + __call() viene attivato quando si + invocano metodi inaccessibili nel contesto di un oggetto. + + + + __callStatic() viene attivato + quando si invocano metodi inaccessibili nel contesto statico. + + + + L'argomento $name è il nome del metodo che viene + chiamato. L'argomento $arguments è un array enumerativo + contenente i parametri passati al metodo $name. + + + + + Overloading dei metodi tramite i metodi <link linkend="object.call">__call()</link> + e <link linkend="object.callstatic">__callStatic()</link> + + + runTest('in object context'); + +MethodTest::runTest('in static context'); +?> +]]> + + &example.outputs; + + + + + + + + + diff --git a/language/oop5/traits.xml b/language/oop5/traits.xml new file mode 100644 index 000000000..44b8b10de --- /dev/null +++ b/language/oop5/traits.xml @@ -0,0 +1,711 @@ + + + + Trait + + PHP implementa un modo per riutilizzare il codice chiamato Trait. + + + I Trait sono un meccanismo per il riutilizzo del codice nei linguaggi a + ereditarietà singola come PHP. Un Trait è pensato per ridurre alcune + limitazioni dell'ereditarietà singola permettendo a uno sviluppatore di + riutilizzare liberamente insiemi di metodi in diverse classi indipendenti + che vivono in diverse gerarchie di classi. La semantica della combinazione + di Trait e classi è definita in modo da ridurre la complessità ed evitare + i tipici problemi associati all'ereditarietà multipla e ai Mixin. + + + Un Trait è simile a una classe, ma è pensato solo per raggruppare + funzionalità in modo granulare e coerente. Non è possibile istanziare un + Trait da solo. È un'aggiunta all'ereditarietà tradizionale e permette la + composizione orizzontale del comportamento; ovvero, l'applicazione di + membri di classe senza richiedere l'ereditarietà. + + + Esempio di Trait + +sayHello(); + echo ' '; + $this->sayWorld(); + echo "!\n"; + } +} + +$myHelloWorld = new MyHelloWorld(); +$myHelloWorld->sayHelloWorld(); + +?> +]]> + + &example.outputs; + + + + + + + Precedenza + + Un membro ereditato da una classe base viene sovrascritto da un membro + inserito da un Trait. L'ordine di precedenza è che i membri della classe + corrente sovrascrivono i metodi del Trait, che a loro volta sovrascrivono + i metodi ereditati. + + + Esempio di ordine di precedenza + + Un metodo ereditato da una classe base viene sovrascritto dal metodo + inserito in MyHelloWorld dal Trait SayWorld. Il comportamento è lo stesso + per i metodi definiti nella classe MyHelloWorld. L'ordine di precedenza + è che i metodi della classe corrente sovrascrivono i metodi del Trait, + che a loro volta sovrascrivono i metodi della classe base. + + +sayHello(); +?> +]]> + + &example.outputs; + + + + + + Esempio alternativo di ordine di precedenza + +sayHello(); +?> +]]> + + &example.outputs; + + + + + + + + Trait multipli + + È possibile inserire più Trait in una classe elencandoli nell'istruzione + use, separati da virgole. + + + Utilizzo di Trait multipli + +sayHello(); +$o->sayWorld(); +$o->sayExclamationMark(); +?> +]]> + + &example.outputs; + + + + + + + + Risoluzione dei conflitti + + Se due Trait inseriscono un metodo con lo stesso nome, viene prodotto un + errore fatale se il conflitto non viene risolto esplicitamente. + + + Per risolvere i conflitti di denominazione tra Trait utilizzati nella stessa + classe, è necessario usare l'operatore insteadof per + scegliere esattamente uno dei metodi in conflitto. + + + Poiché questo permette solo di escludere metodi, l'operatore + as può essere usato per aggiungere un alias a uno dei + metodi. Si noti che l'operatore as non rinomina il + metodo e non influisce su nessun altro metodo. + + + Risoluzione dei conflitti + + In questo esempio, Talker usa i trait A e B. + Poiché A e B hanno metodi in conflitto, viene definito di usare + la variante di smallTalk dal trait B, e la variante di bigTalk dal + trait A. + + + Aliased_Talker fa uso dell'operatore as + per poter usare l'implementazione di bigTalk di B con un alias + aggiuntivo talk. + + + +]]> + + + + + + Modifica della visibilità dei metodi + + Utilizzando la sintassi as, è anche possibile regolare + la visibilità del metodo nella classe che lo espone. + + + Modifica della visibilità dei metodi + + +]]> + + + + + + Trait composti da Trait + + Così come le classi possono usare i trait, anche altri trait possono farlo. + Usando uno o più trait nella definizione di un trait, questo può essere + composto parzialmente o interamente dai membri definiti in quegli altri trait. + + + Trait composti da Trait + +sayHello(); +$o->sayWorld(); +?> +]]> + + &example.outputs; + + + + + + + + Membri astratti dei Trait + + I Trait supportano l'uso di metodi astratti per imporre requisiti + alla classe che li espone. Sono supportati i metodi pubblici, protetti e + privati. Prima di PHP 8.0.0, erano supportati solo i metodi astratti + pubblici e protetti. + + + + A partire da PHP 8.0.0, la firma di un metodo concreto deve seguire le + regole di compatibilità della firma. + In precedenza, la firma poteva essere diversa. + + + + Esprimere requisiti tramite metodi astratti + +getWorld(); + } + abstract public function getWorld(); +} + +class MyHelloWorld { + private $world; + use Hello; + public function getWorld() { + return $this->world; + } + public function setWorld($val) { + $this->world = $val; + } +} +?> +]]> + + + + + + Membri statici dei Trait + + I Trait possono definire variabili statiche, metodi statici e proprietà + statiche. + + + + A partire da PHP 8.1.0, la chiamata di un metodo statico o l'accesso a una + proprietà statica direttamente su un trait è deprecata. I metodi statici e + le proprietà statiche devono essere accessibili solo su una classe che usa + il trait. + + + + Variabili statiche + +inc(); +$p = new C2(); +$p->inc(); + +?> +]]> + + &example.outputs; + + + + + + Metodi statici + + +]]> + + &example.outputs; + + + + + + Proprietà statiche + + + Prima di PHP 8.3.0, le proprietà statiche definite in un trait erano + condivise tra tutte le classi nella stessa gerarchia di ereditarietà che + usavano quel trait. A partire da PHP 8.3.0, se una classe figlia usa un + trait con una proprietà statica, questa sarà considerata distinta da + quella definita nella classe genitore. + + + + +]]> + + &example.outputs.83; + + + + + + + + Proprietà + + I Trait possono anche definire proprietà. + + + Definizione di proprietà + +x; + +?> +]]> + + + + Se un trait definisce una proprietà, una classe non può definire una + proprietà con lo stesso nome a meno che non sia compatibile (stessa + visibilità e tipo, modificatore readonly e valore iniziale), altrimenti + viene emesso un errore fatale. + + + Risoluzione dei conflitti + + +]]> + + + + + + &Constants; + + I Trait possono, a partire da PHP 8.2.0, anche definire costanti. + + + Definizione di costanti + + +]]> + + &example.outputs; + + + + + + Se un trait definisce una costante, una classe non può definire una costante + con lo stesso nome a meno che non sia compatibile (stessa visibilità, valore + iniziale e finalità), altrimenti viene emesso un errore fatale. + + + Risoluzione dei conflitti + + +]]> + + + + + + Metodi final + + A partire da PHP 8.3.0, il modificatore final + può essere applicato usando l'operatore as + ai metodi importati dai trait. Questo può essere usato per impedire alle + classi figlie di sovrascrivere il metodo. Tuttavia, la classe che usa il + trait può comunque sovrascrivere il metodo. + + + Definire un metodo proveniente da un trait come <literal>final</literal> + + +]]> + + &example.outputs.similar; + + + + + + + +