In questo articolo “Il paradigma ad oggetti in PHP” vediamo come sia possibile implementare il paradigma ad oggetti in PHP . Al termine dell’articolo vediamo anche esempi pratici
Indice dei contenuti
Il paradigma a oggetti in PHP
PHP implementa il paradigma degli oggetti (Object-Oriented Paradigm) a partire dalla versione 5.0. Questo paradigma permette di strutturare il codice in classi e oggetti, migliorando l’organizzazione e la riusabilità del codice.
Creazione di una classe in PHP
Per creare una nuova classe, si utilizza il costrutto class
, all’interno del quale vengono definite proprietà (variabili) e metodi (funzioni). Le proprietà devono essere dichiarate con uno dei modificatori di visibilità: public
, private
o protected
.
Ecco la sintassi di base per la dichiarazione di una classe in PHP:
class NomeClasse {
// Proprietà della classe
public $proprieta1;
private $proprieta2;
// Metodo costruttore
public function __construct($valore) {
$this->proprieta1 = $valore;
}
// Metodo pubblico
public function metodoEsempio() {
return "Valore: " . $this->proprieta1;
}
}
Esempio: Classe Carrello
Creiamo ora una classe Carrello, che rappresenta un carrello della spesa. La classe avrà due proprietà:
- $articoli: un array che memorizza gli articoli presenti nel carrello.
- $quantita: un array associativo che tiene traccia della quantità di ogni articolo.
La classe includerà metodi per:
- Aggiungere un articolo al carrello.
- Rimuovere un articolo.
- Visualizzare il contenuto del carrello.
Ecco il codice della classe con i commenti esplicativi:
<?php
class Carrello {
// Proprietà per memorizzare gli articoli e la quantità
private $articoli = [];
private $quantita = [];
// Metodo per aggiungere un articolo al carrello
public function aggiungiArticolo($nomeArticolo, $quantita) {
// Se l'articolo esiste già, aggiorniamo la quantità
if (isset($this->quantita[$nomeArticolo])) {
$this->quantita[$nomeArticolo] += $quantita;
} else {
// Altrimenti, aggiungiamo l'articolo e la quantità
$this->articoli[] = $nomeArticolo;
$this->quantita[$nomeArticolo] = $quantita;
}
}
// Metodo per rimuovere un articolo dal carrello
public function rimuoviArticolo($nomeArticolo) {
if (isset($this->quantita[$nomeArticolo])) {
unset($this->quantita[$nomeArticolo]);
$this->articoli = array_diff($this->articoli, [$nomeArticolo]);
}
}
// Metodo per visualizzare il contenuto del carrello
public function mostraCarrello() {
echo "Contenuto del carrello:\n";
foreach ($this->quantita as $articolo => $qta) {
echo "- $articolo: $qta\n";
}
}
}
// Esempio di utilizzo della classe
$carrello = new Carrello();
$carrello->aggiungiArticolo("Mela", 3);
$carrello->aggiungiArticolo("Pane", 2);
$carrello->aggiungiArticolo("Mela", 1); // Aggiunge altre 1 mela
$carrello->rimuoviArticolo("Pane");
$carrello->mostraCarrello(); //ho aggiunto 3 mele, 2 pane, 1 mela e ho rimosso 2 pane quindi visualizzerò: 4 mele
?>
Spiegazione del codice
In PHP, this
è una parola chiave utilizzata all’interno di una classe per fare riferimento all’istanza corrente dell’oggetto.
Quando creiamo un oggetto da una classe, possiamo usare $this
per accedere alle sue proprietà e metodi all’interno della classe stessa.
Dentro il costruttore :
-
$this->nome = $nome;
→ assegna il valore ricevuto al campo$nome
dell’oggetto attuale.
In un metodo:
-
$this->nome;
→$this->nome
fa riferimento al nome dell’oggetto su cui il metodo è stato chiamato.
Nell’esempio nella riga:
if (isset($this->quantita[$nomeArticolo])) {
La funzione isset()
controlla se la chiave $nomeArticolo
esiste all’interno dell’array $this->quantita
.
$this->quantita
è un array associativo, dove la chiave è il nome dell’articolo e il valore è la quantità.
Se la chiave esiste, significa che l’articolo è già presente nel carrello.
Se l’articolo è già nel carrello, aggiorniamo la quantità:
$this->quantita[$nomeArticolo] += $quantita;
Se l’articolo è già presente, invece di sovrascrivere il valore, lo incrementiamo aggiungendo la nuova quantità specificata come argomento del metodo.
Ad esempio, se il carrello contiene già 2 mele ("Mela" => 2
) e aggiungiamo altre 3 mele, il valore diventa "Mela" => 5
.
Se l’articolo non è presente, lo aggiungiamo:
} else {
$this->articoli[] = $nomeArticolo;
$this->quantita[$nomeArticolo] = $quantita;
}
Se la chiave non esiste, significa che l’articolo non è ancora nel carrello.
Aggiungiamo quindi il nome dell’articolo all’array $this->articoli[]
per tenerne traccia.
Creiamo una nuova chiave in $this->quantita
e le assegniamo la quantità ricevuta.
Nella funzione rimuoviArticolo, La funzione unset()
elimina la chiave corrispondente a $nomeArticolo
dall’array $this->quantita
.
Dopo questa operazione, l’articolo non avrà più una quantità associata.
-
array_diff()
confronta due array e rimuove gli elementi del secondo array dal primo. -
$this->articoli
è l’elenco degli articoli nel carrello (senza le quantità). -
[$nomeArticolo]
è un array che contiene solo l’articolo da eliminare.
Esempio prima dell’operazione Se $this->articoli
contiene:
["Mela", "Pane"]
e chiamiamo rimuoviArticolo("Mela")
, l’operazione:
$this->articoli = array_diff($this->articoli, ["Mela"]);
restituirà:
["Pane"]
La riga di codice nella funzione mostraCarrello:
foreach ($this->quantita as $articolo => $qta)
a parte di un ciclo foreach
, che viene utilizzato per iterare su ogni elemento di un array associativo. In questo caso, l’array è $this->quantita
, che è un array associativo in cui le chiavi sono i nomi degli articoli e i valori sono le quantità degli articoli nel carrello.
Vediamo come funziona dettagliatamente:
Cosa fa foreach
?
Il costrutto foreach
è un ciclo che scorre tutti gli elementi di un array. Per ogni iterazione, restituisce una chiave (in questo caso $articolo
, cioè il nome dell’articolo) e un valore (in questo caso $qta
, cioè la quantità dell’articolo).
Sintassi di foreach
La sintassi del foreach
in PHP è la seguente:
foreach ($array as $chiave => $valore) {
// Codice da eseguire
}
-
$array
è l’array su cui iteriamo (in questo caso,$this->quantita
). -
$chiave
è la chiave dell’elemento dell’array (in questo caso, il nome dell’articolo, come “Mela” o “Pane”). -
$valore
è il valore associato alla chiave nell’array (in questo caso, la quantità, come 3 per “Mela” o 2 per “Pane”).
Esempio pratico
Supponiamo che l’array $this->quantita
contenga:
$this->quantita = [
"Mela" => 3,
"Pane" => 2,
"Latte" => 1
];
Quando usiamo il ciclo foreach
, PHP itera su ogni elemento dell’array $this->quantita
. Alla prima iterazione, la variabile $articolo
sarà "Mela"
e la variabile $qta
sarà 3
. Alla seconda iterazione, $articolo
sarà "Pane"
e $qta
sarà 2
, e così via.
Esecuzione del codice
foreach ($this->quantita as $articolo => $qta) {
echo "$articolo: $qta\n";
}
Il ciclo stampa, riga per riga:
Mela: 3
Pane: 2
Latte: 1
Perché usare foreach
?
Il ciclo foreach
è molto utile quando si lavora con array associativi, come in questo caso. Con foreach
, possiamo facilmente accedere sia alla chiave che al valore senza dover gestire manualmente gli indici, come nel caso di un ciclo for
Costruttori deprecati
A partire da PHP 7, è stato introdotto un cambiamento significativo nella gestione dei costruttori delle classi. In precedenza, con PHP 4, i costruttori avevano la stessa denominazione della classe. Tuttavia, questa pratica ha portato a diversi problemi, in particolare quando si cambiava il nome della classe e bisognava aggiornare tutti i costruttori nei vari file.
Il problema dei costruttori in PHP 4
In PHP 4, la sintassi del costruttore era la seguente:
class Carrello {
function Carrello() {
// codice per inizializzare l'oggetto
}
}
Il costruttore aveva lo stesso nome della classe (in questo caso, Carrello
), ma questo approccio presentava diversi svantaggi:
- Se cambiavi il nome della classe, dovevi modificare anche il nome del costruttore in tutti i file.
- La sintassi risultava poco chiara in alcuni casi, specialmente in scenari di eredità o quando venivano utilizzate classi in framework complessi.
Sintassi deprecata con PHP 7
A partire da PHP 7, questa sintassi è stata deprecata. L’uso di un costruttore con lo stesso nome della classe porta alla visualizzazione di messaggi di avviso e errori. Questo può rappresentare un problema quando si aggiorna il codice, poiché il vecchio formato potrebbe causare una degradazione delle prestazioni e una gestione meno efficiente del codice.
La nuova sintassi del costruttore: __construct()
Per risolvere questo problema, PHP 5 ha introdotto il costruttore generico __construct()
. In questo modo, il costruttore non è più legato al nome della classe, ma a una funzione predefinita che consente di evitare conflitti e migliorare la leggibilità del codice.
La nuova sintassi, introdotta già in PHP 5 e divenuta obbligatoria con PHP 7, prevede l’uso del metodo __construct()
.
Esempio con la nuova sintassi:
<?php
class Carrello {
private $articoli = [];
// Costruttore con la sintassi nuova
public function __construct() {
$this->articoli = [];
echo "Carrello creato!";
}
public function aggiungiArticolo($articolo) {
$this->articoli[] = $articolo;
}
public function mostraArticoli() {
foreach ($this->articoli as $articolo) {
echo $articolo . "<br>";
}
}
}
// Creazione di un oggetto Carrello
$carrello = new Carrello(); // Chiamata al costruttore __construct
$carrello->aggiungiArticolo("Mela");
$carrello->aggiungiArticolo("Pane");
$carrello->mostraArticoli();
?>
Perché usare __construct()
?
-
Compatibilità con le versioni future: PHP 7 ha dichiarato deprecato l’uso del costruttore con il nome della classe e PHP 8 rimuoverà completamente questa funzionalità. Utilizzare
__construct()
è quindi essenziale per garantire la compatibilità futura del codice. -
Chiarezza e manutenzione del codice: Poiché il costruttore è sempre definito come
__construct()
, non dipende più dal nome della classe. Ciò significa che se il nome della classe cambia, non è necessario modificare il nome del costruttore, rendendo il codice più facile da gestire e meno soggetto a errori. -
Ereditarietà: Se la classe viene estesa (ovvero se una classe eredita un’altra classe), il costruttore
__construct()
consente di richiamare facilmente i costruttori delle classi genitore tramiteparent::__construct()
, senza necessità di modificare ogni singolo costruttore delle classi derivate.
L’Ereditarietà in OOP con PHP
L’ereditarietà è uno dei concetti fondamentali della Programmazione Orientata agli Oggetti (OOP). Permette di creare una nuova classe (chiamata classe derivata o classe figlia) che eredita le proprietà e i metodi di una classe esistente (chiamata classe base o classe genitore). La classe derivata può aggiungere nuove funzionalità o modificare (override) quelle ereditate dalla classe base.
In PHP, l’ereditarietà è implementata utilizzando la parola chiave extends
.
Caratteristiche dell’Ereditarietà
- Ereditarietà semplice: PHP supporta l’ereditarietà semplice, cioè una classe può estendere solo una classe base.
- Accesso ai membri: La classe derivata eredita tutte le proprietà e i metodi pubblici e protetti della classe base. Non eredita i membri privati, ma può comunque accedere ai metodi pubblici e protetti della classe base.
Sintassi dell’ereditarietà in PHP
La sintassi per estendere una classe in PHP è la seguente:
class ClasseFiglia extends ClasseBase {
// Nuovi metodi e proprietà
}
Nel caso dell’ereditarietà, la classe figlia può utilizzare tutto ciò che è presente nella classe base, aggiungendo nuove funzionalità o modificando quelle esistenti.
Esempio di Ereditarietà: Classe Carrello e Classe MioCarrello
Immagiamo di avere la nostra classe Carrello, che contiene alcune funzionalità di base per la gestione di articoli. Successivamente, desideriamo creare una classe MioCarrello, che estende Carrello e aggiunge la funzionalità per gestire un prezzo per ogni articolo nel carrello.
class MioCarrello extends Carrello {
private $prezzo;
// Metodo per impostare il prezzo
public function setPrezzo($prezzo) {
$this->prezzo = $prezzo;
}
// Metodo per ottenere il prezzo
public function getPrezzo() {
return $this->prezzo;
}
// Metodo per mostrare articoli e prezzo
public function mostraArticoliConPrezzo() {
foreach ($this->articoli as $articolo) {
echo $articolo . " - Prezzo: " . $this->prezzo . "<br>";
}
}
}
Spiegazione del codice:
-
Classe Carrello (Base):
- Ha una proprietà protetta
$articoli
, che è un array che contiene gli articoli nel carrello. - Il metodo
aggiungiArticolo($articolo)
aggiunge un articolo al carrello. - Il metodo
mostraArticoli()
stampa gli articoli nel carrello.
- Ha una proprietà protetta
-
Classe MioCarrello (Derivata):
-
extends Carrello
: La classe MioCarrello estende la classe Carrello. Ciò significa che eredita le proprietà e i metodi della classe Carrello. -
$prezzo
è una nuova proprietà che memorizza il prezzo degli articoli nel carrello. - Il metodo
setPrezzo($prezzo)
imposta il prezzo. - Il metodo
getPrezzo()
restituisce il prezzo. - Il metodo
mostraArticoliConPrezzo()
mostra gli articoli nel carrello insieme al prezzo.
-
Poichè la classe Carrello
definisce $articoli
come una proprietà privata, essa non può essere accessibile direttamente dalla classe derivata MioCarrello
.
Quando si provia ad usare $this->articoli
in MioCarrello
, PHP non trova questa proprietà, e quindi restituisce un errore del tipo “Undefined property”.
Soluzione:
Per risolvere il problema, hai due opzioni:
-
Rendere la proprietà
articoli
protetta (protected
): In questo modo la proprietà sarà accessibile dalla classe derivata. Questo è il metodo che utilizzeremo - Fornire un metodo pubblico nella classe base per accedere agli articoli.
Opzione 1: Rendere articoli
protected
Si deve cambiare la visibilità della proprietà $articoli
da private
a protected
. In questo modo, la classe MioCarrello
potrà accedere direttamente a questa proprietà.
Ora vediamo un esempio di utilizzo. Dopo aver creato la classe Carrello e la classe MioCarrello che estende Carrello, creiamo due script PHP per le due classi (Carrello.php e MioCarrello.php) e creiamo lo script PHP provaCarello.php:
<?php
//richiamiamo gli script che contengono le classi carrello_new e MioCarrello
require_once("Carrello.php");
require_once("MioCarrello.php");
$carrello = new MioCarrello();
$carrello->aggiungiArticolo("Mela");
$carrello->aggiungiArticolo("Pane");
// Impostiamo il prezzo per gli articoli
$carrello->setPrezzo(2.5);
// Mostriamo gli articoli con il prezzo
$carrello->mostraArticoliConPrezzo();
?>
Output:
Mela - Prezzo: 2.5
Pane - Prezzo: 2.5
Perché usare l’Ereditarietà?
- Riutilizzo del codice: La classe derivata riutilizza il codice della classe base, senza doverlo riscrivere. Questo rende il codice più conciso e manutenibile.
- Estensione delle funzionalità: Puoi aggiungere nuove funzionalità alla classe derivata senza alterare il comportamento della classe base.
- Semplificazione della manutenzione: Modificare il comportamento di una classe base si riflette automaticamente su tutte le classi derivate, riducendo la necessità di aggiornamenti duplicati.
Limiti dell’Ereditarietà in PHP
- Ereditarietà semplice: PHP supporta solo l’ereditarietà semplice, quindi una classe può estendere solo una classe base. Non è possibile ereditare da più classi contemporaneamente.
- Ereditarietà vs Composizione: In alcuni casi, la composizione (cioè l’inclusione di oggetti di altre classi) è preferita rispetto all’ereditarietà per una maggiore flessibilità e per evitare una struttura troppo rigida.
Nella sezione DOWNLOAD o direttamente da qui: https://profgiagnotti.it/download/4860/?tmstv=1744539632 è possibile scaricare gli script descritti nell’articolo
Lascia un commento