PHP orientato agli oggetti per principianti
() translation by (you can also view the original English article)
Per molti programmatori PHP la programmazione orientata agli oggetti è un concetto che spaventa, pieno di sintassi complicata e di altri ostacoli. Come ho scritto nei dettagli nel mio libro, Pro PHP and jQuery (in inglese), imparerete i concetti dietro la programmazione orientata agli oggetti (in inglese object-oriented programming, OOP), uno stile di scrittura di codice dove si raggruppano azioni collegate in classi per poter creare codice più compatto e più efficiente.
Capire la programmazione orientata agli oggetti
La programmazione orientata agli oggetti è uno stile di scrittura di codice che permette agli sviluppatori di raggruppare compiti simili in classi. Questo aiuta a far sì che il codice segua il principio "non ripeterti" (in inglese don't repeat yourself, DRY) e sia facile da manutenere.
"La programmazione orientata agli oggetti è uno stile di scrittura di codice che permette agli sviluppatori di raggruppare compiti simili in classi".
Uno dei maggiori vantaggi del principio di programmazione DRY è che, se cambia un pezzo di informazione nel vostro programma, di solito è necessaria una sola modifica per aggiornare il codice. Uno dei più grandi incubi per gli sviluppatori è manutenere codice dove i dati sono dichiarati mille volte, il che vuol dire che ogni modifica al programma diventa un gioco infinitamente più frustrante di Dov'è Wally? per cercare le funzionalità e i dati duplicati.
L'OOP può intimidire molti sviluppatori, perché introduce sintassi nuova e, a un primo sguardo, appare ben più complessa del semplice codice procedurale, o riga per riga. Comunque, se la si guarda più da vicino, l'OOP è in realtà un approccio molto immediato e sostanzialmente più semplice alla programmazione.
Capire gli oggetti e le classi
Prima di andare troppo a fondo nelle sottigliezze dell'OOP è necessaria una comprensione di base delle differenze tra oggetti e classi. Questa sezione esaminerà i componenti fondamentali delle classi, le loro differenti capacità e alcuni dei loro usi.
Riconoscere le differenze tra oggetti e classi

Gli sviluppatori iniziano a parlare di oggetti e di classi, e questi sembrano essere termini interscambiabili. Non è così, comunque.
Tanto per cominciare, c'è confusione nell'OOP: gli sviluppatori esperti iniziano a parlare di oggetti e di classi, e questi sembrano essere termini interscambiabili. Non è così, comunque, anche se la differenza può essere difficile da iniziare a capire subito.
Una classe, per esempio, è come un progetto per una casa. Definisce su carta la forma della casa, con relazioni ben definite e pianificate tra le diverse parti della casa, anche se la casa non esiste.
Un oggetto, quindi, è come la casa vera e propria costruita secondo quel progetto. I dati memorizzati nell'oggetto sono come il legno, i cavi e il cemento che compongono la casa: senza essere messi insieme secondo il progetto, sono solo un mucchio di roba. Comunque, quando si mette tutto insieme, diventa una casa utile e organizzata.
Le classi formano la struttura dei dati e delle azioni e usano queste informazioni per costruire gli oggetti. Si può costruire più di un oggetto contemporaneamente dalla stessa classe, e ciascuno è indipendente dagli altri. Continuando con la nostra analogia edilizia, è simile al modo di costruire un intero isolato dallo stesso progetto: 150 case diverse che hanno tutte lo stesso aspetto ma hanno dentro famiglie diverse
e un diverso arredamento.
Strutturare le classi
La sintassi per creare una classe è piuttosto immediata: si dichiara una classe usando la parola chiave class
, seguita dal nome della classe e da un insieme di parentesi graffe ({}
):
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
// Class properties and methods go here
|
6 |
}
|
7 |
|
8 |
?>
|
Dopo aver creato la classe, si può istanziare la classe e memorizzarla in una variabile usando la parola chiave new
:
1 |
$obj = new MyClass; |
Per vedere il contenuto della classe si usa var_dump()
:
1 |
var_dump($obj); |
Provate questo procedimento mettendo il codice precedente in un nuovo file di nome test.php
nella cartella [locale] di test:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
// Class properties and methods go here
|
6 |
}
|
7 |
|
8 |
$obj = new MyClass; |
9 |
|
10 |
var_dump($obj); |
11 |
|
12 |
?>
|
Caricate la pagina nel vostro browser all'URL http://localhost/test.php
e si dovrebbe vedere quanto segue:
1 |
object(MyClass)#1 (0) { } |
Nella sua forma più semplice, avete appena completato il vostro primo script OOP.
Definire le proprietà di una classe
Per aggiungere dati a una classe si usano le proprietà, o variabili specifiche della classe. Queste funzionano esattamente come le variabili normali, tranne per il fatto che sono legate all'oggetto e perciò vi si può accedere solo usando l'oggetto.
Per aggiungere una proprietà a MyClass
aggiungete il seguente codice al vostro script:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
}
|
7 |
|
8 |
$obj = new MyClass; |
9 |
|
10 |
var_dump($obj); |
11 |
|
12 |
?>
|
La parola chiave public
determina la visibilità della proprietà, sulla quale imparerete un po' più avanti in questo capitolo. In seguito si dà un nome alla proprietà usando la sintassi standard per le variabili e si assegna un valore (sebbene le proprietà delle classi non abbiano bisogno di un valore iniziale).
Per leggere questa proprietà e visualizzarla nel browser si fa riferimento all'oggetto da cui leggere e alla proprietà da leggere:
1 |
echo $obj->prop1; |
Poiché possono esistere multiple istanze di una classe, se non si facesse riferimento al singolo oggetto lo script non sarebbe in grado di determinare da quale oggetto leggere. L'uso della freccia (->
) è un costrutto OOP per accedere alle proprietà e ai metodi contenuti in un dato oggetto:
Modificate lo script in test.php
per leggere la proprietà invece di visualizzare l'intera classe modificando il codice così:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
}
|
7 |
|
8 |
$obj = new MyClass; |
9 |
|
10 |
echo $obj->prop1; // Output the property |
11 |
|
12 |
?>
|
Se ricaricate il browser ora vedrete quanto segue:
1 |
I'm a class property! |
Definire i metodi di una classe
I metodi sono funzioni specifiche della classe. Si definiscono all'interno della classe come metodi le singole azioni che un oggetto sarà in grado di eseguire.
Per esempio, per creare metodi che scrivono e leggono il valore della proprietà $prop1
della classe aggiungete al vostro codice quanto segue:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function setProperty($newval) |
8 |
{
|
9 |
$this->prop1 = $newval; |
10 |
}
|
11 |
|
12 |
public function getProperty() |
13 |
{
|
14 |
return $this->prop1 . "<br />"; |
15 |
}
|
16 |
}
|
17 |
|
18 |
$obj = new MyClass; |
19 |
|
20 |
echo $obj->prop1; |
21 |
|
22 |
?>
|
Nota — l'OOP permette agli oggetti di far riferimento a loro stessi usando $this
. Quando si lavora all'interno di un metodo si usa $this
come si usarebbe il nome dell'oggetto al di fuori della classe.
Per usare questi metodi li si chiamano come funzioni normali, ma prima si fa riferimento all'oggetto al quale appartengono. Leggete la proprietà da MyClass
, modificate il suo valore e leggetela di nuovo facendo la modifica seguente:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function setProperty($newval) |
8 |
{
|
9 |
$this->prop1 = $newval; |
10 |
}
|
11 |
|
12 |
public function getProperty() |
13 |
{
|
14 |
return $this->prop1 . "<br />"; |
15 |
}
|
16 |
}
|
17 |
|
18 |
$obj = new MyClass; |
19 |
|
20 |
echo $obj->getProperty(); // Get the property value |
21 |
|
22 |
$obj->setProperty("I'm a new property value!"); // Set a new one |
23 |
|
24 |
echo $obj->getProperty(); // Read it out again to show the change |
25 |
|
26 |
?>
|
Ricaricate il browser e vedrete quanto segue:
1 |
I'm a class property! |
2 |
I'm a new property value! |
"Il potere dell'OOP si nota quando si usano istanze multiple della
stessa classe".
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function setProperty($newval) |
8 |
{
|
9 |
$this->prop1 = $newval; |
10 |
}
|
11 |
|
12 |
public function getProperty() |
13 |
{
|
14 |
return $this->prop1 . "<br />"; |
15 |
}
|
16 |
}
|
17 |
|
18 |
// Create two objects
|
19 |
$obj = new MyClass; |
20 |
$obj2 = new MyClass; |
21 |
|
22 |
// Get the value of $prop1 from both objects
|
23 |
echo $obj->getProperty(); |
24 |
echo $obj2->getProperty(); |
25 |
|
26 |
// Set new values for both objects
|
27 |
$obj->setProperty("I'm a new property value!"); |
28 |
$obj2->setProperty("I belong to the second instance!"); |
29 |
|
30 |
// Output both objects' $prop1 value
|
31 |
echo $obj->getProperty(); |
32 |
echo $obj2->getProperty(); |
33 |
|
34 |
?>
|
Quando ricaricate il risultato nel browser appare quello che segue:
1 |
I'm a class property! |
2 |
I'm a class property! |
3 |
I'm a new property value! |
4 |
I belong to the second instance! |
Come potete vedere, l'OOP considera gli oggetti entità separate, e ciò permette una facile separazione dei vari pezzi di codice in piccoli gruppi separati.
Metodi magici nell'OOP
Per rendere più facile l'uso degli oggetti il PHP fornisce anche un certo numero di metodi magici, o metodi speciali che vengono chiamati quando occorrono determinate azioni comuni all'interno degli oggetti. Questo permette agli sviluppatori di eseguire diversi compiti utili con una certa facilità.
Usare i costruttori e i distruttori
Quando viene istanziato un oggetto spesso si desidera impostare alcune cose subito dall'inizio. Per gestire questo il PHP fornisce il metodo magico __construct()
, che viene chiamato automaticamente ogni volta che si crea un nuovo
oggetto.
Al fine di illustrare il concetto dei costruttori, aggiungiamo a MyClass
un costruttore che restituirà un messaggio ogni volta che si crea una nuova istanza della classe:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function setProperty($newval) |
13 |
{
|
14 |
$this->prop1 = $newval; |
15 |
}
|
16 |
|
17 |
public function getProperty() |
18 |
{
|
19 |
return $this->prop1 . "<br />"; |
20 |
}
|
21 |
}
|
22 |
|
23 |
// Create a new object
|
24 |
$obj = new MyClass; |
25 |
|
26 |
// Get the value of $prop1
|
27 |
echo $obj->getProperty(); |
28 |
|
29 |
// Output a message at the end of the file
|
30 |
echo "End of file.<br />"; |
31 |
|
32 |
?>
|
Nota —__CLASS__
restituisce il nome della classe nella quale è chiamato, per questo è noto come costante magica. Ci sono varie costanti magiche disponibili, potete leggere di più a questo proposito nel manuale PHP.
Ricaricare il file nel browser produrrà il seguente risultato:
1 |
The class "MyClass" was initiated! |
2 |
I'm a class property! |
3 |
End of file. |
Per chiamare una funzione quando l'oggetto viene distrutto è disponibile il metodo magico __destruct()
. Questo è utile per fare pulizia nelle classi (per esempio per chiudere una connessione a un database).
Visualizzate un messaggio quando viene distrutto l'oggetto definendo il metodo magico__destruct()
in MyClass
:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function setProperty($newval) |
18 |
{
|
19 |
$this->prop1 = $newval; |
20 |
}
|
21 |
|
22 |
public function getProperty() |
23 |
{
|
24 |
return $this->prop1 . "<br />"; |
25 |
}
|
26 |
}
|
27 |
|
28 |
// Create a new object
|
29 |
$obj = new MyClass; |
30 |
|
31 |
// Get the value of $prop1
|
32 |
echo $obj->getProperty(); |
33 |
|
34 |
// Output a message at the end of the file
|
35 |
echo "End of file.<br />"; |
36 |
|
37 |
?>
|
Con un distruttore definito, ricaricare il file di test darà il seguente risultato:
1 |
The class "MyClass" was initiated! |
2 |
I'm a class property! |
3 |
End of file. |
4 |
The class "MyClass" was destroyed. |
"Quando si raggiunge la fine di un file il PHP libera automaticamente tutte le risorse".
Per attivare esplicitamente il distruttore si può distruggere l'oggetto usando la
funzione unset()
:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function setProperty($newval) |
18 |
{
|
19 |
$this->prop1 = $newval; |
20 |
}
|
21 |
|
22 |
public function getProperty() |
23 |
{
|
24 |
return $this->prop1 . "<br />"; |
25 |
}
|
26 |
}
|
27 |
|
28 |
// Create a new object
|
29 |
$obj = new MyClass; |
30 |
|
31 |
// Get the value of $prop1
|
32 |
echo $obj->getProperty(); |
33 |
|
34 |
// Destroy the object
|
35 |
unset($obj); |
36 |
|
37 |
// Output a message at the end of the file
|
38 |
echo "End of file.<br />"; |
39 |
|
40 |
?>
|
Ora il risultato cambia come segue se caricato nel browser:
1 |
The class "MyClass" was initiated! |
2 |
I'm a class property! |
3 |
The class "MyClass" was destroyed. |
4 |
End of file. |
Convertire in stringa
Per evitare un errore se uno script cerca di visualizzare MyClass
come stringa si usa un altro metodo magico di nome __toString()
.
Senza __toString()
un tentativo di visualizzare l'oggetto come stringa darebbe un errore fatale. Tentativo di usare echo
per visualizzare l'oggetto senza che ci sia un metodo magico:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function setProperty($newval) |
18 |
{
|
19 |
$this->prop1 = $newval; |
20 |
}
|
21 |
|
22 |
public function getProperty() |
23 |
{
|
24 |
return $this->prop1 . "<br />"; |
25 |
}
|
26 |
}
|
27 |
|
28 |
// Create a new object
|
29 |
$obj = new MyClass; |
30 |
|
31 |
// Output the object as a string
|
32 |
echo $obj; |
33 |
|
34 |
// Destroy the object
|
35 |
unset($obj); |
36 |
|
37 |
// Output a message at the end of the file
|
38 |
echo "End of file.<br />"; |
39 |
|
40 |
?>
|
Questo dà il seguente risultato:
1 |
The class "MyClass" was initiated! |
2 |
|
3 |
Catchable fatal error: Object of class MyClass could not be converted to string in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 40 |
Per evitare questo errore aggiungiamo un metodo __toString()
:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
public function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
// Create a new object
|
35 |
$obj = new MyClass; |
36 |
|
37 |
// Output the object as a string
|
38 |
echo $obj; |
39 |
|
40 |
// Destroy the object
|
41 |
unset($obj); |
42 |
|
43 |
// Output a message at the end of the file
|
44 |
echo "End of file.<br />"; |
45 |
|
46 |
?>
|
In questo caso un tentativo di convertire l'oggetto in stringa dà come risultato una chiamata al metodo getProperty()
. Caricate lo script nel browser per vedere il risultato:
1 |
The class "MyClass" was initiated! |
2 |
Using the toString method: I'm a class property! |
3 |
The class "MyClass" was destroyed. |
4 |
End of file. |
Consiglio — In aggiunta ai metodi magici discussi in questa sezione, ne sono disponibili altri. Per una lista completa dei metodi magici si veda la pagina del manuale PHP.
Usare l'ereditarietà
Le classi possono ereditare i metodi e le proprietà di un'altra classe usando la parola chiave extends
. Per esempio, per creare una seconda classe che estende MyClass
e aggiunge un metodo si può aggiungere il seguente codice al file:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
public function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function newMethod() |
37 |
{
|
38 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
39 |
}
|
40 |
}
|
41 |
|
42 |
// Create a new object
|
43 |
$newobj = new MyOtherClass; |
44 |
|
45 |
// Output the object as a string
|
46 |
echo $newobj->newMethod(); |
47 |
|
48 |
// Use a method from the parent class
|
49 |
echo $newobj->getProperty(); |
50 |
|
51 |
?>
|
Ricaricando il file nel browser si ha il seguente risultato:
1 |
The class "MyClass" was initiated! |
2 |
From a new method in MyOtherClass. |
3 |
I'm a class property! |
4 |
The class "MyClass" was destroyed. |
Sovrascrivere proprietà e metodi ereditati
Per modificare il comportamento di una proprietà o di un metodo esistente nella nuova classe si può semplicemente sovrascriverlo dichiarandolo di nuovo nella nuova classe:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
public function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function __construct() |
37 |
{
|
38 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
39 |
}
|
40 |
|
41 |
public function newMethod() |
42 |
{
|
43 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
44 |
}
|
45 |
}
|
46 |
|
47 |
// Create a new object
|
48 |
$newobj = new MyOtherClass; |
49 |
|
50 |
// Output the object as a string
|
51 |
echo $newobj->newMethod(); |
52 |
|
53 |
// Use a method from the parent class
|
54 |
echo $newobj->getProperty(); |
55 |
|
56 |
?>
|
Questo cambia il risultato nel browser:
1 |
A new constructor in MyOtherClass. |
2 |
From a new method in MyOtherClass. |
3 |
I'm a class property! |
4 |
The class "MyClass" was destroyed. |
Conservare la funzionalità originale del metodo quando si sovrascrivono i metodi
Per aggiungere una nuova funzionalità a un metodo ereditato conservando intatto il metodo originale si usa la parola chiave parent
con l'operatore di risoluzione di visibilità (::
):
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
public function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function __construct() |
37 |
{
|
38 |
parent::__construct(); // Call the parent class's constructor |
39 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
40 |
}
|
41 |
|
42 |
public function newMethod() |
43 |
{
|
44 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
45 |
}
|
46 |
}
|
47 |
|
48 |
// Create a new object
|
49 |
$newobj = new MyOtherClass; |
50 |
|
51 |
// Output the object as a string
|
52 |
echo $newobj->newMethod(); |
53 |
|
54 |
// Use a method from the parent class
|
55 |
echo $newobj->getProperty(); |
56 |
|
57 |
?>
|
Questo restituisce il risultato sia del costruttore padre che del costruttore della nuova classe:
1 |
The class "MyClass" was initiated! |
2 |
A new constructor in MyOtherClass. |
3 |
From a new method in MyOtherClass. |
4 |
I'm a class property! |
5 |
The class "MyClass" was destroyed. |
Assegnare la visibilità alle proprietà e ai metodi
Per un maggior controllo sugli oggetti si assegna una visibilità ai metodi e alle proprietà. Questo controlla come e da dove si può accedere a metodi e proprietà. Ci sono tre parole chiave di visibilità: public
, protected
e private
. Oltre alla visibilità, una proprietà o un metodo può essere dichiarato static
, che permette l'accesso senza un'istanziazione della classe.
"Per un maggior controllo sugli oggetti si assegna una visibilità ai metodi e alle proprietà".
Nota — La visibilità è una nuova funzionalità dal PHP 5 in poi. Per informazioni sulla compatibilità OOP con il PHP 4 si veda la pagina del manuale PHP.
Proprietà e metodi pubblici
Tutte le proprietà e tutti i metodi usati finora sono stati pubblici. Questo significa che vi si può accedere ovunque, sia dentro la classe che fuori.
Proprietà e metodi protetti
Quando una proprietà o un metodo è dichiarato protected
vi si può accedere solo all'interno della classe stessa o delle sue classi discendenti (classi che estendono la classe che contiene il metodo protetto).
Dichiarate il metodo getProperty()
protetto in MyClass
e provate ad accedere ad esso direttamente al di fuori della classe:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
protected function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function __construct() |
37 |
{
|
38 |
parent::__construct(); |
39 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
40 |
}
|
41 |
|
42 |
public function newMethod() |
43 |
{
|
44 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
45 |
}
|
46 |
}
|
47 |
|
48 |
// Create a new object
|
49 |
$newobj = new MyOtherClass; |
50 |
|
51 |
// Attempt to call a protected method
|
52 |
echo $newobj->getProperty(); |
53 |
|
54 |
?>
|
Provando a eseguire questo script appare il seguente errore:
1 |
The class "MyClass" was initiated! |
2 |
A new constructor in MyOtherClass. |
3 |
|
4 |
Fatal error: Call to protected method MyClass::getProperty() from context '' in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 55 |
Ora create un metodo in MyOtherClass
che chiami il metodo getProperty()
:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
protected function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function __construct() |
37 |
{
|
38 |
parent::__construct(); |
39 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
40 |
}
|
41 |
|
42 |
public function newMethod() |
43 |
{
|
44 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
45 |
}
|
46 |
|
47 |
public function callProtected() |
48 |
{
|
49 |
return $this->getProperty(); |
50 |
}
|
51 |
}
|
52 |
|
53 |
// Create a new object
|
54 |
$newobj = new MyOtherClass; |
55 |
|
56 |
// Call the protected method from within a public method
|
57 |
echo $newobj->callProtected(); |
58 |
|
59 |
?>
|
Questo genera il risultato desiderato:
1 |
The class "MyClass" was initiated! |
2 |
A new constructor in MyOtherClass. |
3 |
I'm a class property! |
4 |
The class "MyClass" was destroyed. |
Proprietà e metodi privati
Una proprietà o un metodo dichiarato private
è accessibile solo all'interno della classe che lo definisce. Questo vuol dire che anche se una nuova classe estende la classe che definisce una proprietà privata, quella proprietà o quel metodo non sarà affatto disponibile all'interno della classe figlia.
Per dimostrare questo, dichiarate privato getProperty()
in MyClass
e provate a chiamare callProtected()
daMyOtherClass
:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public function __construct() |
8 |
{
|
9 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
10 |
}
|
11 |
|
12 |
public function __destruct() |
13 |
{
|
14 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
15 |
}
|
16 |
|
17 |
public function __toString() |
18 |
{
|
19 |
echo "Using the toString method: "; |
20 |
return $this->getProperty(); |
21 |
}
|
22 |
|
23 |
public function setProperty($newval) |
24 |
{
|
25 |
$this->prop1 = $newval; |
26 |
}
|
27 |
|
28 |
private function getProperty() |
29 |
{
|
30 |
return $this->prop1 . "<br />"; |
31 |
}
|
32 |
}
|
33 |
|
34 |
class MyOtherClass extends MyClass |
35 |
{
|
36 |
public function __construct() |
37 |
{
|
38 |
parent::__construct(); |
39 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
40 |
}
|
41 |
|
42 |
public function newMethod() |
43 |
{
|
44 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
45 |
}
|
46 |
|
47 |
public function callProtected() |
48 |
{
|
49 |
return $this->getProperty(); |
50 |
}
|
51 |
}
|
52 |
|
53 |
// Create a new object
|
54 |
$newobj = new MyOtherClass; |
55 |
|
56 |
// Use a method from the parent class
|
57 |
echo $newobj->callProtected(); |
58 |
|
59 |
?>
|
Ricaricate il browser e apparirà il seguente errore:
1 |
The class "MyClass" was initiated! |
2 |
A new constructor in MyOtherClass. |
3 |
|
4 |
Fatal error: Call to private method MyClass::getProperty() from context 'MyOtherClass' in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 49 |
Proprietà e metodi statici
A una proprietà o a un metodo dichiarato static
si può accedere senza prima istanziare la classe; si scrive semplicemente il nome della classe, l'operatore di risoluzione di visibilità e il nome della proprietà o del metodo.
"Uno dei vantaggi maggiori di usare proprietà statiche è che mantengono in memoria il loro valore per tutta la durata dello script".
Per dimostrare questo aggiungete una proprietà statica di nome $count
e un metodo statico di nome plusOne()
a MyClass
. Poi impostate un ciclo do...while
per visualizzare il valore incrementato di $count
finché il valore è minore di 10:
1 |
<?php
|
2 |
|
3 |
class MyClass |
4 |
{
|
5 |
public $prop1 = "I'm a class property!"; |
6 |
|
7 |
public static $count = 0; |
8 |
|
9 |
public function __construct() |
10 |
{
|
11 |
echo 'The class "', __CLASS__, '" was initiated!<br />'; |
12 |
}
|
13 |
|
14 |
public function __destruct() |
15 |
{
|
16 |
echo 'The class "', __CLASS__, '" was destroyed.<br />'; |
17 |
}
|
18 |
|
19 |
public function __toString() |
20 |
{
|
21 |
echo "Using the toString method: "; |
22 |
return $this->getProperty(); |
23 |
}
|
24 |
|
25 |
public function setProperty($newval) |
26 |
{
|
27 |
$this->prop1 = $newval; |
28 |
}
|
29 |
|
30 |
private function getProperty() |
31 |
{
|
32 |
return $this->prop1 . "<br />"; |
33 |
}
|
34 |
|
35 |
public static function plusOne() |
36 |
{
|
37 |
return "The count is " . ++self::$count . ".<br />"; |
38 |
}
|
39 |
}
|
40 |
|
41 |
class MyOtherClass extends MyClass |
42 |
{
|
43 |
public function __construct() |
44 |
{
|
45 |
parent::__construct(); |
46 |
echo "A new constructor in " . __CLASS__ . ".<br />"; |
47 |
}
|
48 |
|
49 |
public function newMethod() |
50 |
{
|
51 |
echo "From a new method in " . __CLASS__ . ".<br />"; |
52 |
}
|
53 |
|
54 |
public function callProtected() |
55 |
{
|
56 |
return $this->getProperty(); |
57 |
}
|
58 |
}
|
59 |
|
60 |
do
|
61 |
{
|
62 |
// Call plusOne without instantiating MyClass
|
63 |
echo MyClass::plusOne(); |
64 |
} while ( MyClass::$count < 10 ); |
65 |
|
66 |
?>
|
Nota — Quando si accede a proprietà statiche, il segno del dollaro
($
) viene dopo l'operatore di risoluzione di visibilità.
Quando si carica lo script nel browser il risultato è il seguente:
1 |
The count is 1. |
2 |
The count is 2. |
3 |
The count is 3. |
4 |
The count is 4. |
5 |
The count is 5. |
6 |
The count is 6. |
7 |
The count is 7. |
8 |
The count is 8. |
9 |
The count is 9. |
10 |
The count is 10. |
Commentare con i DocBlock
"Lo stile di commento DocBlock è un metodo
ampiamente accettato per documentare le classi".
Sebbene non faccia ufficialmente parte dell'OOP, lo stile di commento DocBlock è un metodo ampiamente accettato per documentare le classi. Oltre a fornire uno standard che gli
sviluppatori usano quando scrivono codice, è anche stato adottato da molti dei più popolari strumenti di sviluppo software, come Eclipse e NetBeans, e sarà usato per usare suggerimenti di codice.
Si definisce un DocBlock usando un commento a blocco che inizia con un asterisco in più:
1 |
/**
|
2 |
* This is a very basic DocBlock
|
3 |
*/
|
Il vero potere del DocBlock sta nella capacità di usare i tag, che iniziano con una chiocciola (@
) immediatamente seguita dal nome del tag e dal suo valore. I tag dei DocBlock permettono agli sviluppatori di definire gli autori di un file, la licenza per una classe, informazioni su proprietà e metodi e altre informazioni utili.
Seguono i tag più comunemente usati:
- @author: Con questo tag si elenca l'autore dell'elemento corrente (che può essere una classe, un file, un metodo o un qualunque pezzo di codice). Si possono usare nello stesso DocBlock più tag author se si vuole dar credito a più di un autore. Il formato per il nome di un autore è
Mario Rossi <mario.rossi@email.com>
. - @copyright: Questo significa l'anno di copyright e il nome del detentore del copyright per l'elemento corrente. Il formato è
2010 Detentore Del Copyright
. - @licenza: Questo è un link alla licenza per l'elemento corrente. Il formato per le informazioni sulla licenza è
http://www.esempio.com/percorso/alla/licenza.txt Nome Della Licenza
. - @var: Contiente il tipo e la descrizione di una variabile o proprietà della classe. Il formato è
tipo descrizione dell'elemento
. - @param: Questo tag mostra il tipo e la descrizione del parametro di una funzione o metodo. Il formato è
tipo $nome_elemento descrizione dell'elemento
- @return: Questo tag fornisce il tipo e la descrizione del valore restituito da una funzione o metodo. Il formato è
tipo descrizione dell'elemento restituito
.
Un esempio di classe commentata con i DocBlock ha questo aspetto:
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* A simple class
|
5 |
*
|
6 |
* This is the long description for this class,
|
7 |
* which can span as many lines as needed. It is
|
8 |
* not required, whereas the short description is
|
9 |
* necessary.
|
10 |
*
|
11 |
* It can also span multiple paragraphs if the
|
12 |
* description merits that much verbiage.
|
13 |
*
|
14 |
* @author Jason Lengstorf <jason.lengstorf@ennuidesign.com>
|
15 |
* @copyright 2010 Ennui Design
|
16 |
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
17 |
*/
|
18 |
class SimpleClass |
19 |
{
|
20 |
/**
|
21 |
* A public variable
|
22 |
*
|
23 |
* @var string stores data for the class
|
24 |
*/
|
25 |
public $foo; |
26 |
|
27 |
/**
|
28 |
* Sets $foo to a new value upon class instantiation
|
29 |
*
|
30 |
* @param string $val a value required for the class
|
31 |
* @return void
|
32 |
*/
|
33 |
public function __construct($val) |
34 |
{
|
35 |
$this->foo = $val; |
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Multiplies two integers
|
40 |
*
|
41 |
* Accepts a pair of integers and returns the
|
42 |
* product of the two.
|
43 |
*
|
44 |
* @param int $bat a number to be multiplied
|
45 |
* @param int $baz a number to be multiplied
|
46 |
* @return int the product of the two parameters
|
47 |
*/
|
48 |
public function bar($bat, $baz) |
49 |
{
|
50 |
return $bat * $baz; |
51 |
}
|
52 |
}
|
53 |
|
54 |
?>
|
Se guardate bene la classe precedente, i vantaggi dei DocBlock sono chiari: tutto è ben definito in modo che il prossimo sviluppatore possa prendere il codice e non si debba mai chiedere cosa fa o cosa dovrebbe contenere un pezzo di codice.
Confronto tra codice orientato agli oggetti e procedurale
Non esiste un modo giusto o un modo sbagliato di scrivere codice. Detto questo, questa sezione delinea una forte argomentazione per adottare un approccio orientato agli oggetti nello sviluppo di software, specialmente in grandi progetti.
Ragione 1: Facilità di implementazione
"Anche se può intimorire all'inizio, l'OOP in realtà fornisce un approccio più facile per gestire i dati".
Anche se può intimorire all'inizio, l'OOP in realtà fornisce un approccio più facile per gestire i dati. Poiché un oggetto può memorizzare dati al suo interno, non è necessario passare variabili da una funzione all'altra perché tutto funzioni correttamente.
Inoltre, poiché possono esistere contemporaneamente più istanze della stessa classe, è infinitamente più facile gestire grandi insiemi di dati. Per esempio, supponiamo di dover elaborare le informazioni di due persone in un file. Ci servono i nomi, le occupazioni e le età.
L'approccio procedurale
Questo è l'approccio procedurale al nostro esempio:
1 |
<?php
|
2 |
|
3 |
function changeJob($person, $newjob) |
4 |
{
|
5 |
$person['job'] = $newjob; // Change the person's job |
6 |
return $person; |
7 |
}
|
8 |
|
9 |
function happyBirthday($person) |
10 |
{
|
11 |
++$person['age']; // Add 1 to the person's age |
12 |
return $person; |
13 |
}
|
14 |
|
15 |
$person1 = array( |
16 |
'name' => 'Tom', |
17 |
'job' => 'Button-Pusher', |
18 |
'age' => 34 |
19 |
);
|
20 |
|
21 |
$person2 = array( |
22 |
'name' => 'John', |
23 |
'job' => 'Lever-Puller', |
24 |
'age' => 41 |
25 |
);
|
26 |
|
27 |
// Output the starting values for the people
|
28 |
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; |
29 |
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; |
30 |
|
31 |
// Tom got a promotion and had a birthday
|
32 |
$person1 = changeJob($person1, 'Box-Mover'); |
33 |
$person1 = happyBirthday($person1); |
34 |
|
35 |
// John just had a birthday
|
36 |
$person2 = happyBirthday($person2); |
37 |
|
38 |
// Output the new values for the people
|
39 |
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; |
40 |
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; |
41 |
|
42 |
?>
|
Quando si esegue, il codice restituisce quanto segue:
1 |
Person 1: Array |
2 |
(
|
3 |
[name] => Tom |
4 |
[job] => Button-Pusher |
5 |
[age] => 34 |
6 |
)
|
7 |
Person 2: Array |
8 |
(
|
9 |
[name] => John |
10 |
[job] => Lever-Puller |
11 |
[age] => 41 |
12 |
)
|
13 |
Person 1: Array |
14 |
(
|
15 |
[name] => Tom |
16 |
[job] => Box-Mover |
17 |
[age] => 35 |
18 |
)
|
19 |
Person 2: Array |
20 |
(
|
21 |
[name] => John |
22 |
[job] => Lever-Puller |
23 |
[age] => 42 |
24 |
)
|
Sebbene il codice non sia necessariamente pessimo, c'è molto da tener presente quando si scrive. L'array con gli attributi della persona in questione deve essere passato e restituito da ogni chiamata di funzione, cosa che lascia un margine di errore.
Per rendere l'esempio più pulito, sarebbe desiderabile lasciare allo sviluppatore meno cose possibili. Alle funzioni dovrebbe essere necessario passare solo le informazioni assolutamente essenziali per l'operazione corrente.
È qui che arriva l'OOP ad aiutare a rendere le cose più pulite.
L'approccio OOP
Ecco l'approccio OOP al nostro esempio:
1 |
<?php
|
2 |
|
3 |
class Person |
4 |
{
|
5 |
private $_name; |
6 |
private $_job; |
7 |
private $_age; |
8 |
|
9 |
public function __construct($name, $job, $age) |
10 |
{
|
11 |
$this->_name = $name; |
12 |
$this->_job = $job; |
13 |
$this->_age = $age; |
14 |
}
|
15 |
|
16 |
public function changeJob($newjob) |
17 |
{
|
18 |
$this->_job = $newjob; |
19 |
}
|
20 |
|
21 |
public function happyBirthday() |
22 |
{
|
23 |
++$this->_age; |
24 |
}
|
25 |
}
|
26 |
|
27 |
// Create two new people
|
28 |
$person1 = new Person("Tom", "Button-Pusher", 34); |
29 |
$person2 = new Person("John", "Lever Puller", 41); |
30 |
|
31 |
// Output their starting point
|
32 |
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; |
33 |
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; |
34 |
|
35 |
// Give Tom a promotion and a birthday
|
36 |
$person1->changeJob("Box-Mover"); |
37 |
$person1->happyBirthday(); |
38 |
|
39 |
// John just gets a year older
|
40 |
$person2->happyBirthday(); |
41 |
|
42 |
// Output the ending values
|
43 |
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; |
44 |
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; |
45 |
|
46 |
?>
|
Questo restituisce il seguente risultato nel browser:
1 |
Person 1: Person Object |
2 |
(
|
3 |
[_name:private] => Tom |
4 |
[_job:private] => Button-Pusher |
5 |
[_age:private] => 34 |
6 |
)
|
7 |
|
8 |
Person 2: Person Object |
9 |
(
|
10 |
[_name:private] => John |
11 |
[_job:private] => Lever Puller |
12 |
[_age:private] => 41 |
13 |
)
|
14 |
|
15 |
Person 1: Person Object |
16 |
(
|
17 |
[_name:private] => Tom |
18 |
[_job:private] => Box-Mover |
19 |
[_age:private] => 35 |
20 |
)
|
21 |
|
22 |
Person 2: Person Object |
23 |
(
|
24 |
[_name:private] => John |
25 |
[_job:private] => Lever Puller |
26 |
[_age:private] => 42 |
27 |
)
|
C'è un po' più di lavoro iniziale per realizzare l'approccio orientato agli oggetti, ma una volta che la classe è definita, creare e modificare una persona è un attimo; le informazioni di una persona non devono essere passate o restituite dai metodi, e ad ogni metodo si passano solo le informazioni assolutamente essenziali.
"L'OOP ridurrà significativamente il vostro carico di lavoro se implementata correttamente".
Su una piccola scala questa differenza potrà non sembrare granché, ma come la vostra applicazione crescerà di dimensione l'OOP ridurrà significativamente il vostro carico di lavoro se implementata correttamente.
Consiglio — Non tutto deve essere orientato agli oggetti. Una funzione rapida che gestisce qualcosa di piccolo in un posto solo all'interno dell'applicazione non deve necessariamente far parte di una qualche classe. Usate il vostro giudizio quando dovete decidere tra un approccio procedurale e uno orientato agli oggetti.
Ragione 2: Migliore organizzazione
Un altro vantaggio dell'OOP è come si presta bene ad essere facilmente impacchettata e catalogata. Ogni classe si può generalmente tenere in un suo file separato, e se si una una convenzione uniforme per i nomi accedere alle classi è estremamente semplice.
Supponiamo di avere un'applicazione con 150 classi che sono chiamate dinamicamente da un file di controllo alla radice del filesystem della nostra applicazione. Tutte le 150 classi seguono la convenzione per i nomi class.nomeclasse.inc.php
e risiedono nella cartella inc
della nostra applicazione.
Il file di controllo può implementare la funzione __autoload()
del PHP per caricare dinamicamente solo le classi necessarie quando vengono chiamate, piuttosto che includerle tutte e 150 nel file di controllo nel caso che servano o trovare qualche modo abile per includere i file nel nostro codice:
1 |
<?php
|
2 |
function __autoload($class_name) |
3 |
{
|
4 |
include_once 'inc/class.' . $class_name . '.inc.php'; |
5 |
}
|
6 |
?>
|
Avere ogni classe in un file separato rende anche il codice più portabile e più facile da riutilizzare in nuove applicazioni senza troppo copia e incolla.
Ragione 3: Manutenzione più facile
A causa della natura più compatta dell'OOP quando è fatta correttamente, le modifiche nel codice sono di solito molto più facili da individuare e da fare che in una lunga implementazione procedurale a spaghetti.
Se un array particolare deve avere un nuovo attributo, un pezzo di software procedurale può richiedere (nel caso peggiore) che il nuovo attributo sia aggiunto a ogni funzione che usa l'array.
Un'applicazione OOP potrebbe potenzialmente essere aggiornata facilmente aggiungendo la nuova proprietà e poi aggiungendo i metodi che gestiscono quella proprietà.
Molti dei vantaggi coperti in questa sezione sono il prodotto della OOP in combinazione con le pratice di programmazione DRY: È decisamente possibile creare codice procedurale facile da manutenere che non causi incubi, ed è altrettanto possibile creare pessimo codice orientato agli oggetti. [Pro PHP and jQuery] cercherà di dimostrare che una combinazione di buone abitudini quando si scrive codice insieme all'OOP genera codice che è facile da leggere e da manutenere.
Riassunto
A questo punto dovreste sentirvi a vostro agio con lo stile di programmazione orientato agli oggetti. Imparare l'OOP è un buon modo per portare la vostra programmazione al livello successivo. Se implementata correttamente, la OOP vi aiuterà a produrre codice facile da leggere, facile da manutenere, portabile e che risparmierà (a voi e agli sviluppatori che lavorano con voi) ore di lavoro in più. Siete bloccati su qualcosa che non è stato trattato in questo articolo? State già usando l'OOP e avete consigli per i principianti? Commentate!
Nota dell'autore — Questo tutorial era un estratto da Pro PHP and jQuery (Apress, 2010).