Sei sulla pagina 1di 89

PHP

PHP è un linguaggio che può essere eseguito lato server. E’ open-source, OOP ed è
interpretato, il che vuol dire che non deve essere compilato per poter essere
eseguito.
E’ veloce e sicuro.

Usiamo PHP perché:


interagisce con il database e viene embeddato nel HTML per mostrare dati in
maniera dinamica
può creare le sessioni
può accedere e settare i cookies
aiuta a cryptare i dati e a creare validazioni
supporta diversi protocolli come HTTP, SMTP, POP3 ecc..
PUO’ GESTIRE I FORM

Variabili
In PHP le variabili si inizializzano con la seguente sintassi
$nomeVariabile;
$nomeVariabile = valore;

PHP è un linguaggio loosely typed, ciò vuol dire che non dobbiamo specificare il tipo
di dato che deve immagazzinare una variabile. Questa analisi viene fatta
direttamente dal linguaggio.

Per inizializzare una variabile in maniera corretta dobbiamo ricordarci che:


deve iniziare con il simbolo $
il nome della variabile può contenere caratteri alfanumerici e l’underscore _
il nome della variabile deve iniziare con una lettera o con l’underscore, non può
iniziare con un numero e non può contenere spazi
$pippo; //lecita
$_pippo; //lecita
$1pippo; // non lecita
$pi ppo; // non lecita
le variabili in PHP sono case-sensitive
$pippo != $Pippo;

Scope delle variabili


In PHP una variabile è visibile all’interno della porzione di codice in cui è dichiarata.

 
In questo esempio, all’inizio del programma, $pippo contiene la stringa “Pippo”.
Nel corpo della funzione, $pippo viene ridichiarata e quindi conterrà la stringa
“Paperino”. Una volta terminata la funzione, la variabile $pippo ridichiarata al suo
interno viene eliminata dalla memoria e il valore di $pippo torna ad essere “Pippo”.
La variabile $pluto, una volta terminata la funzione, non esiste più e, quando
proveremo a stamparla, ci dirà che non è definita.

Possiamo individuare 2 tipi di scope, in questo caso.


La variabile $pippo fuori dalla funzione ha scope globale perché si trova nel blocco
più esterno ed è “visibile” in tutto il programma.
La variabile $pippo all’interno della funzione ha scope locale alla funzione perché
nasce e muore al suo interno.

Constant variables
Le variabili di questo genere hanno due particolarità:
non possono essere modificate
hanno scope globale
 

La funzione printx() ha accesso alla variabile X const e può stamparla anche se il suo
scope non è globale.

Data types
PHP può gestire 8 tipi di dato e vengono suddivisi in 3 categorie:
predefiniti o scalari
composti o user-defined
speciali
 

1. Predefiniti
sono i tipi di dato nativi del linguaggio e si suddividono in:
boolean
integer
float
string

boolean: rappresenta solo due valori, true o false


integer: rappresenta i numeri interi, positivi e negativi, in base 10, base 8  e base
16
float: rappresenta i numeri a virgola mobile positivi e negativi
string: rappresenta le sequenze di caratteri alfanumerici e/o caratteri speciali.
Una stringa è delimitata dai singoli o dai doppi apici
$str = "Ciao, il mio nome è pippo!" //stringa valida 
$str = 'Ciao, il mio nome è pippo!' //stringa valida 
$str = Ciao, il mio nome è pippo! //stringa non valida
$str = <<<IDT
Ciao sono una stringa 
su più righe
IDT;
La differenza tra i singoli e i doppi apici è che all’interno dei doppi apici, le variabili
venogno interpretate.
 

2. composti o user-defined
i tipi di dati composti o user-defined sono diversi dai primitivi poiché possono
contenere diversi tipi di dati predefiniti e composti.
Si suddividono in array e oggetti.

array: un array è una collezione di valori che possono essere dello stesso tipo o di
tipi diversi.
Es.

Array di stringhe
 
Es.  Array di valori di tipi di versi

Gli array possono essere dichiarati anche usando le parentesi quadre

Ogni valore ha un indice che indica la sua posizione all’interno dell’array. Questo
indice serve ad accedere all’elemento. 
GLI INDICI DELL’ARRAY IN PHP PARTONO DA 0. QUINDI, PER ACCEDERE AL
PRIMO ELEMENTO DELL’ARRAY, DOBBIAMO RIFERIRCI ALL’INDICE 0.

Possiamo avere anche array di array. In questo caso, l’array $valori contiene 3 array al
suo interno.
 

Per accedere a un elemento in un array di array, dobbiamo utilizzare due indici. Il


primo sarà l’indice dell’array contenuto e il secondo l’indice dell’elemento all’interno
dell’array contenuto.
Es
 

Array associativi o key => value


Gli arrai associativi sono degli array che per ogni elemento associano ogni elemento
al loro interno a una chiave.
 

Es
 
 
 

oggetti: LI VEDREMO PIU’ AVANTI


speciali: PER ORA NON VI INTERESSANO
OPERATORI
Gli operatori sono dei simboli che eseguono delle operazioni sugli operandi

. operatori matematici
in caso di molteplici operatori nella stessa espressione, valgono le regole di
precedenza matematica

. operatori di confronto
confrontano gli operandi e restituiscono true o false in base all’operatore

es.
 

L’operatore === controlla sia il valore che il tipo di dato e ritorna true quando
entrambi gli operandi sono uguali in tipo e in valore
 

. operatori logici
and: si indica con il simbolo & e restituisce true solo se i due operandi su cui
agisce sono true
or: si indica con il simbolo | e restituisce true solo se almeno uno dei due
operandi su cui agisce è true

. String operator
l’operatore che vediamo per le stringhe è l’operatore della concatenazione che
si indica con il . (punto)
$str1 = "Ciao";
$str2 = "Mondo";
echo $str1 . " " . $str2; //Ciao Mondo
// equivale a fare 
echo "$str1 $str2";

Teorema di Bohm-Jacopini
“qualunque algoritmo può essere implementato utilizzando tre sole strutture, la
sequenza, la selezione e il ciclo, da applicare ricorsivamente alla composizione di
istruzioni elementari“.

Selezione
Ad un certo punto, potremmo trovarci in una situazione in cui vogliamo far fare delle
cose al nostro programma a seconda di alcune condizioni.
Il classico esempio è l’accesso al sito se e solo se l’utente è maggiorenne.

Quindi, se l’utente è maggiorenne, il nostro programma dovrà fare alcune cose. Farà
altre, altrimenti.

In questo caso, ci viene in aiuto il costrutto IF…ELSE


Questo costrutto è formato in questa maniera
 

Alla prima riga del costrutto, viene valutata la condizione che deve essere verificata.
Se questa è vera, allora esegui il codice che si trova all’interno delle prime graffe.
Se la condizione risulta falsa, esegui il codice che si trova nelle graffe dopo l’else.
Nel nostro caso diamo per scontato che l’utente sia maggiorenne
 

In questo caso, $userAge contiene il valore 20.


Alla riga 3, il valore 20 verrà sostituito a $userAge e il programma potrà confrontare
se 20 è maggiore o uguale a 18. Dato che questo confronto ritorna true perché 20 >
18, la condizione sarà 

valutata come vera e verrà eseguito il primo ramo dell’if.


Se $userAge fosse minore di 18, la condizione sarebbe valutata falsa e verrebbe
eseguito il ramo else dell’if.

Così come l’else, possiamo anche concatenare più condizioni. Ad esempio, se il


nostro utente ha 18 anni, verrà eseguito un codice. Se ha 20 anni, verrà eseguito un
altro.
 

In questo caso, se la prima condizione non è vera, verrà controllata la seconda. Se la


seconda risulta vera, viene eseguito il codice nel secondo ramo dell’if. Se entrambe le
condizioni risultano false, verrà eseguito il codice nel ramo else.

Switch, l’alternativa a milioni di If


In un mondo ideale, dopo le condizioni da verificare non si limitano per forza a due o
tre casi, è impensabile dover implementare tanti if quante sono le condizioni.
Per casi del genere, possiamo utilizzare il costrutto SWITCH.

**esempio senza break, 


 

Il costrutto switch consiste nella valutazione di un’espressione e l’esecuzione di uno


dei suoi case in base al risultato della valutazione.
Facciamo un esempio: chiediamo all’utente di inserire un colore e, in base al colore
che inserisce, facciamo qualcosa.
 

In questo caso, l’utente scriverà una stringa che verrà memorizzata nella variabile
$colore.
Questa stringa verrà valutata dalla switch e, se sarà uguale a uno dei case presenti
nella switch, verrà eseguito il codice del case corrispondente.
Se così non fosse, verrà eseguito il codice presente nel default case.
In caso di riscontro positivo, invece, verrà eseguito il codice e la switch terminerà la
sua funzione con l’istruzione break.

Iterazione
I costrutti di iterazione sono 4:
for
foreach
while
do…while
hanno delle differenze strutturali e vengono utilizzati in base alle esigenze.

1.for
Il cilco for è utile quando conosciamo il numero di volte (iterazioni) in cui devono
essere eseguite le istruzioni all’interno del ciclo.
E’ strutturato in questa maniera:
**for annidati, fibonacci

indice di inizio: il valore del contatore al primo ciclo


incremento/decremento dell’indice: il passo con cui vogliamo incrementare
l’indice dopo ogni iterazione
condizione: la condizione che deve essere soddisfatta per permettere al ciclo di
continuare

Esempio. Voglio stampare tutti i numeri da 1 a 10


 

In questo caso:
il contatore inizia da 1
viene incrementato di uno dopo ogni esecuzione
quando diventa maggiore di 10, non soddisfa più la condizione e il ciclo viene
interrotto

Quindi, alla prima iterazione $i vale 1, 1 è minore o uguale di 10 quindi la condizione è


vera e il ciclo viene eseguito. Alla fine del ciclo, $i viene incrementata di 1.
Alla seconda iterazione $i vale 2, 2 è minore o uguale di 10 quindi la condizione è
vera e il ciclo viene eseguito e…
Quando, all’undicesima iterazione $i vale 11, $i non sarà più minore o uguale a 10, la
condizione verrà valutata falsa e il ciclo terminerà passando il controllo
dell’esecuzione all’istruzione successiva.
 

2. foreach
Il ciclo foreach viene utilizzato per ciclare gli array, cioè effettuare delle
operazione per ogni elemento che compone l’array.
Ad esempio, abbiamo un array di studenti e, per ognuno, vogliamo mostrare il
nome.
 

Il foreach prende come parametro un array e, per ogni sua iterazione, crea una
variabile in cui salverà l’elemento che sta ciclando in questo momento.
Quindi, alla prima iterazione su $students, $student conterrà il valore “Andrea”. Alla
seconda iterazione, $student conterrà il valore “Marco” e così via.

Possiamo ciclare anche un array associativo accedendo alle chiavi e ai valori con le
keyword $key e $value
Es.
 

In questo modo, per ogni iterazione, si accederà alla coppia key => value e, tramite la
keyword $key, possiamo accedere alla key.

3. while
Il ciclo while differisce in struttura e logica dal for.
Questo ciclo viene eseguito quando non si conosce il numero di iterazioni che si
devono eseguire.
Questo ciclo esegui il codice al suo interno fino a quando la condizione non
diventa falsa.
 

Come prima, vogliamo mostrare tutti i numeri compresi tra 1 e 10


 

L’esecuzione avviene in questo modo


Effettua il controllo sulla condizione. Dato che $i = 1 e 1 <= 10, la condizione viene
valutata true e il codice viene eseguito. Alla fine del ciclo, la variabile $i viene
incrementata, quindi $i = 2. L’esecuzione torna al controllo della condizione. $i = 2, 2
<= 10, la condizione è vera quindi il codice viene eseguito ecc…

4. do…while
Il do while si differenzia dal while perché il primo ciclo viene sempre eseguito.
 

In questo caso, il primo ciclo viene effettuato e poi viene valutata la condizione.
Se la condizione risulta vera, il secondo ciclo viene effettuato e così via.

Facciamo lo stesso esempio di prima con il do while


 

In questo caso, il primo ciclo verrà eseguito, verrà stampato il numero 12 e poi verrà
controllata la condizione. La condizione verrà valutata falsa e il programma
continuerà con la normale esecuzione.

BREAK
Per stoppare l’esecuzione del ciclo e far riprendere l’esecuzione dalla prima
istruzione successiva, possiamo utilizzare l’istruzione break.
Ad esempio, vogliamo far terminare il ciclo se si avvera una condizione.
 

CONTINUE
Con il continue possiamo terminare l’esecuzione di un’iterazione del ciclo.
Ad esempio, se il numero ciclato non è dispari, passa al numero successivo
 

FUNZIONI
Una funzione è una porzione di codice che può essere eseguito più volte durante un
programma.
Di solito le funzioni restituiscono un valore o mostrano qualcosa all’utente.
Un esempio di funzione che mostra qualcosa all’utente è var_dump che ci mostra
che tipo di dato contiene una variabile e qual è il valore del dato al suo interno. 

Le funzioni sono principalmente di due tipi: built-in functions e user functions.

Built-in functions
Quasi tutti i linguaggi di programmazione hanno delle funzioni già scritte che
l’utente può richiamare.
Ad esempio, vogliamo mostrare il contenuto di una variabile all’utente

funzioni per manipolare gli array


https://www.w3schools.com/php/php_ref_array.asp

Es. COUNT
Vogliamo sapere quanti elementi sono presenti all’interno di un array
 

In questo caso, verrà eseguita prima la funzione count, che ritorna il numero degli
elementi di un array e poi verrà eseguita la funzione var_dump che ci stamperà il
risultato di count.

Array methods

. array_change_key_case() :  cambia tutte le keys dell’array associativo in uppercase


o lowercase
Questa funzione prende in ingresso due parametri: l’array su cui deve agire e il
case in cui deve trasformare le keys.
Per trasformarle in maiuscolo si usa CASE_UPPER, per trasformarle in minuscolo
si usa CASE_LOWER
 

. array_chunk(): Array chunk divide gli elementi dell’array su cui viene chiamata in
sottoarray.
ATTENZIONE.. NON CREA UN NUOVO ARRAY, SEMPLICEMENTE UNISCE GLI
ELEMENTI ALL’INTERNO IN SOTTOARRAY.
Come parametri accetta l’array su cui deve agire e il numero di elementi che deve
formare ogni sotto array
In questo esempio, passiamo come parametri, l’array $cities e il numero 2 per
indicare che l’array $cities deve essere diviso in sotto array formati da 2 elementi.
Ovviamente, se rimane un numero di elementi inferiore al numero che indichiamo
nella funzione, verrà creato un altro sottoarray con gli elementi rimanenti

 
. array_column(): accetta come parametri l’array su cui deve agire e una delle sue
chiavi. 
Cicla l’array che passiamo come parametro e restituisce, per ogni elemento al suo
interno, il valore che abbiamo passato come secondo parametro.
array_column($array, column_key)
 

Possiamo passare più di due parametri alla funzione array column ma non più di 3.
Il terzo parametro verrà attribuito come chiave ad ogni coppia chiave valore dell’array
risultante
array_column($array, column_key, index_key)
In questo esempio passiamo $teachers come array da manipolare, ‘surname’ come
valore che restituirà per ogni elemento dell’array e ‘name’ come chiave per ogni
valore.
Quindi, ad ogni valore ‘surname’ corrisponderà la chiave ‘name’

. array_combine(): prende in ingresso due array e restituisce un nuovo array


associativo dove le chiavi sono gli elementi del primo array e i valori sono gli
elementi del secondo array

array_combine( $arr1, $arr2 );


 

Se gli array hanno lunghezza diversa, la funzione ritornerà un errore.

User functions
Le user functions, manco a dirlo, sono le funzioni create dall’utente.

Una funzione viene dichiarata utilizzando la parola chiave function. 


Quindi la sintassi è:
 

Le funzioni possono ricevere anche dei parametri che devono manipolare nelle
istruzioni che ci sono al loro interno.
Ad esempio, se volessimo fare una banale somma tra due numeri tramite una
funzione, dobbiamo passare alla funzione i dati che deve elaborare
 

Come possiamo vedere, una funzione viene dichiarata e poi viene chiamata.
La dichiarazione di funzione serve a istruire il programma su cosa deve fare quando
la funzione viene poi richiamata a riga 11.

Parametri
$num1 e $num2 nella dichiarazione di funzione sono chiamati parametri formali
poichè vengono utilizzati nella dichiarazione per dire alla funzione che ha bisogno di
due parametri per funzionare e quindi, quando a riga 11 andiamo a richiamarla,
dobbiamo passare per forza due parametri.
I parametri che passiamo alla chiamata, $a e $b, sono chiamati parametri reali
perché sono proprio quelli che verranno utilizzati e manipolati dalla funzione.

Parametri passati per valore 


Ma cosa succede quando passiamo dei parametri a una funzione?
In PHP, i parametri vengono passati per valore. Ma cosa vuol dire?
A riga 11, quando chiamiamo la funzione passando i parametri reali, viene allocato un
nuovo spazio in memoria per l’esecuzione della funzione. La funzione, per come
l’abbiamo istruita, si aspetta due parametri in ingresso. Il programma crea due
variabili interne alla funzione a cui assegna il valore presente nelle variabili reali.
In questo modo $num1 = $a e $num2 = $b.

Parametri passati per riferimento


A differenza del passaggio per valore, il parametro formale all’interno della funzione
non è più una copia del parametro reale ma un riferimento alla sua locazione di
memoria. In questo modo la funzione ha accesso alla variabile reale e può
modificarla
 

All’inizio del programma, $a = 5. Passiamo il riferimento ( l’indirizzo di memoria in cui


è salvata la variabile $a ) alla funzione che può modificare il suo contenuto. 

Parametri di default
Ci possiamo trovare nel caso in cui il nostro programma non riesce a passare i
parametri alla funzione. Ma, come abbiamo visto prima, le funzioni devono ricevere
tante variabili reali all’esecuzione tante quante sono le variabili formali alla
dichiarazione.
Cioè, se nella dichiarazione di funzione, diciamo che per funzionare dobbiamo
passare 2 parametri, alla chiamata devono essere passati due parametri.
In questo caso, possiamo assegnare dei valori di default ai parametri che utilizzerà la
funzione.

Alla chiamata di funzione, a riga 8, passiamo solo un parametro reale, anche se la


funzione se ne aspetta due.
Come funziona?
Al momento della chiamata, viene allocato uno spazio in memoria per la funzione e
vengono istanziate due variabili. In $num1 viene memorizzato il valore di $a e, non
avendo ricevuto il secondo parametro reale, utilizza quello di default

Parametri variabili
Ci sono dei casi in cui non sappiamo quanti parametri riceverà la funzione. In questo
caso possiamo usare una dicitura particolare nella dichiarazione di funzione.

In questo caso, tutti i parametri reali che passiamo alla funzione verranno salvati
nell’array $numbers locale alla funzione.
Valore di ritorno
Una funzione molto spesso può anche restituire un valore come risultato della sua
esecuzione.
Nell‘esempio precedente abbiamo visto come fare la somma tra due numeri e
mostrare il risultato all’utente. 
E se volessimo salvare il valore della somma in modo da non perderlo dopo
l’esecuzione della funzione?

Per far restituire un valore a una funzione, utilizziamo la keyword return


 

In questo caso, a riga 7, diciamo alla funzione che deve restituire il risultato della
somma tra i due parametri che passiamo alla funzione e salviamo questo risultato in
una nuova variabile in modo da avere a portata di mano il risultato della funzione.
OOP: Object Oriented Programming
Questo paradigma di progettazione si basa sul concetto di classe. 
Una classe è una descrizione di un tipo di dato.
Per esempio, diciamo che vogliamo rappresentare un tipo di dato Persona.
Sappiamo che ogni persona ha un nome, un cognome e un’età.
Sarebbe logico rappresentarli in questa maniera:

Pensiamo ora di voler creare un’altra persona o altre 100. Sarebbe impensabile dover
creare tanti array quante sono le persone da istanziare.

Una classe ci aiuterebbe a creare un modello con le stesse caratteristiche per tutte le
persone
Vediamo come
 

In questo modo abbiamo descritto  quali sono gli attributi che un oggetto ( variabile
di classe persona ) deve avere per essere definito di tipo persona.
Possiamo vedere che gli attributi della classe persona rispecchiano le chiavi nell’array
$persona1.

Come le funzioni, la dichiarazione di una classe non implica che ci sia un oggetto di
tipo persona in memoria. La classe è solo una descrizione.

Vediamo come si crea un oggetto di classe Persona


 

Analizziamo bene questo snippet.


Da riga 1 a riga 15 abbiamo la dichiarazione della classe Persona.
Da riga 4 a riga 6 abbiamo le proprietà che un oggetto deve avere per essere di
tipo persona
Da riga 8 a riga 13 abbiamo la funzione che costruisce l’oggetto
Da riga 10 a riga 12 ci sono le assegnazioni dei valori. Analizziamo bene
la prima cosa che salta all’occhio è la “variabile” $this. Quando si crea un
nuovo oggetto di una determinata classe, viene creato un token identificativo
per ogni oggetto creato. Ciò vuol dire che $this è un riferimento univoco
all’oggetto. Ad esempio, a riga 17 stiamo creando un oggetto di classe persona
e lo stiamo memorizzando nella variabile $andrea. $this, in questo caso, sarà
un riferimento a $andrea. Quindi, il linguaggio creerà una variabile di nome
$andrea, assocerà un token e assegnerà la stringa “Andrea” all’attributo nome
della variabile $andrea.
 A riga 17, lanciamo l’istruzione che richiama la funzione __construct della classe a
cui passiamo i parametri necessari per valorizzare gli attributi dell’oggetto. 

Così come accediamo ai valori di un array tramite la chiave, possiamo accedere a un


attributo della classe tramite il suo nome.
Vediamo come

Logicamente, se avessimo due oggetti di classe Persona


Per accedere al nome di $andrea, dovrei richiamare l’attributo nome su $andrea
$andrea->nome; //Andrea
Per accedere al nome di $francesco, dovrei richiamare l’attributo nome su
$francesco
$francesco->nome; //Francesco

Object functions
Logicamente, le persone possono compiere delle azioni, tipo presentarsi.
Proprio come le persone, le classi possono implementare dei metodi. 
Il nostro oggetto di classe persona vuole potersi presentare, istruiamo la classe.
In questo caso, istruire la classe vuol dire creare un metodo ( funzione delle classi )
all’interno della classe.

Nella funzione presentati() abbiamo creato una stringa in cui richiamiamo il nome, il
cognome e l’eta dell’oggetto di classe.
Abbiamo usato la keyword $this perché vogliamo che, ogni volta che richiamiamo la
funzione presentati su un oggetto, questa acceda alle proprietà dell’oggetto su cui è
richiamata. 

ATTRIBUTI  E METODI STATICI


I metodi e le proprietà statiche possono essere richiamati senza istanziare un
oggetto di quella classe.
Mettiamoci per qualche minuto nei panni di Dio o chiunque voi crediate abbia creato
la vita sulla Terra. A un certo punto, ci accorgiamo che vogliamo tenere il conto delle
persone che abbiamo creato. In questo caso una bella proprietà statica fa proprio al
caso nostro.

 
Come vediamo nell’esempio, un attributo di tipo statico va dichiarato tra gli attributi
di classe e possiamo accedervi, come vediamo a riga 21, direttamente dalla classe.
Quindi, per accedere alle proprietà statiche della classe, basta scrivere
NomeClasse::nomeProprietà

Così come abbiamo gli attributi statici, abbiamo anche i metodi statici, che possono
essere richiamati anche senza istanziare un oggetto di quella classe.
Ora, Dio può vedere quante persone ha creato ma è brutto rispondere a Dio solo con
il numero, non è educato. Creiamo un metodo che risponda al Creatore in una
maniera più carina.

 
E’ evidente il motivo per cui la funzione ritorna 2 esseri umani, ma entriamo nel
dettaglio.
Abbiamo detto che, ogni volta che usiamo la keyword new per creare un oggetto,
viene chiamata la funzione costruttore della classe. Nel nostro caso, dopo aver
assegnato tutti i valori all’oggetto, la stessa funzione costruttore incrementa il valore
dell’attributo statico $count, incrementando così il contatore ogni volta che viene
lanciata la funzione costruttore.

Analizziamo la keyword self. Come this serve ad accedere a un attributo dell’oggetto


su cui è richiamato, self serve ad accedere un attributo statico della classe.

COSA SUCCEDE IN MEMORIA?


Quando creiamo una classe, viene allocata una porzione di memoria che conterrà la
descrizione della classe con i metodi statici e i metodi di classe.
Quando istanziamo un oggetto di una determinata classe, verrà allocata una
porzione di memoria che conterrà gli attributi dell’oggetto.
 

Quindi:
classe → proprietà statiche di classe, metodi statici di classe e metodi
oggetto → attributi dell’oggetto
 Prendendo l’esempio di sopra:
  nella porzione di memoria dedicata alla classe
static $count , static function quantiUmani(), static function increment(),
static function decrement()
nella porzione di memoria dedicata all’oggetto
public $nome, $cognome e $eta.
Come funziona quindi l’accesso alle proprietà e a i metodi statici? 
Prendiamo questo esempio
$coach è un oggetto di classe Persona.
Dato che ogni oggetto istanziato in memoria ha un riferimento alla porzione di
memoria in cui è istanziata la descrizione della classe a cui appartiene, l’oggetto può
accedere alle proprietà statiche e ai metodi statici della classe.
Vediamo come

Mentre prima abbiamo visto come accedere alle proprietà statiche e ai metodi statici
della classe Persona facendo riferimento proprio alla classe, ora vediamo come
accedere agli attributi statici e ai metodi statici tramite l’oggetto

Access modifiers
Nella nostra classe, notiamo che gli attributi sono dichiarati public.
Ma cosa vuol dire? Quella parola prima dell’attributo indica lo scope ( la visibilità ) e
chi può accedere a quell’attributo.
. public: si può accedere dall’esterno della classe

In questo caso, posso accedere liberamente dall’esterno della classe all’attributo


nome dell’oggetto $andrea.
Ma cosa vuol dire accedere dall’esterno? Vuol dire che accedo a un attributo,
semplicemente richiamando dall’oggetto.

. protected
Un attributo protected non può essere letto dall’esterno come un attributo public.
Può essere visto solo dalla classe in cui è dichiarata e dalle classi che la estendono (
lo vedremo dopo )
 

In questo caso, l’attributo cognome è protected. Ciò vuol dire che può essere letto
solo dall’interno della classe. Se dovessimo provare a stamparlo con
var_dump($andrea→cognome), avremmo un errore.
Per potervi accedere, quindi, abbiamo creato una funzione interna alla classe che ci
permette di poter stampare il valore dell’attributo.
 
 
Oltre alla lettura, un altro esempio di accessibilità potrebbe essere la modifica di un
attributo.
Diciamo che il nostro carissimo $andrea non deve più chiamarsi Andrea. Cioè, il
valore dell’attributo nome di $andrea deve essere diverso da Andrea.

Nell’esempio, l’attributo $nome della classe persona è public, quindi accessibile


dall’esterno. L’attributo $cognome, invece, è protected, quindi non accessibile
dall’esterno.
Così come abbiamo richiamato un’attributo public tramite il nome e un attributo
protected tramite funzione per poterli visualizzare, possiamo fare lo stesso per
modificare i loro valori.
 
 
. private
Gli attributi di tipo private possono essere visti SOLO dalla classe in cui sono
dichiarati.

EREDITARIETA’
Come abbiamo visto negli esempi in alto, è utile classificare le persone perché hanno
degli attributi in comune. 
Tuttavia, le persone hanno anche degli attributi che li contraddistinguono. 
Prendiamo come esempio una scuola e la dividiamo in due sottocategorie principali:
docenti
studenti
Logicamente, docenti e studenti rientrano nella categoria delle persone poiché tutti i
docenti e tutti gli studenti hanno un nome, un cognome e un’età.
Possiamo fare una distinzione, per esempio, in quanto i docenti hanno delle materie
da insegnare e gli studenti hanno una media voti.

Quindi, dato che i docenti e gli studenti conservano le stesse proprietà della classe
Persona e ne implementano una tutta nuova che appartiene solo alla loro classe,
possiamo dire che le classi Docente e Studente, estendono la classe Persona.
Facciamo un esempio
 
 Per promemoria, ecco la nostra classe Persona
 

Ora vediamo come le classi Docente e Studente, estendono la classe Persona


 

 
Per indicare che una classe che stiamo descrivendo estende un’altra classe già
esistente, si utilizza la keyword extends nome_classe_che_viene_estesa

Nel nostro caso, class Docente extends Persona.

In entrambi i casi, notiamo che, nella funzione costruttore delle classi che estendono
Persona, andiamo a costruire gli attributi che le sottoclassi ereditano, tramite il
costruttore della classe padre.
Per spiegarci meglio, le classi che estendono Persona, ereditano da questa gli
attributi $nome, $cognome e $eta. Questi attributi ereditati, vengono costruiti dalla
classe genitore, nel nostro caso la classe Persona.
Come facciamo a comunicare questa cosa al nostro programma? Richiamando il
costruttore del padre. Riga 16 per la classe Docente, riga 7 per la classe Studente.

E’ giusto precisare che le classi che estendono, erediteranno solo le proprietà e i


metodi dichiarati public e protected. Tutto ciò che è private, rimane interno alla
singola classe in cui questo attributo o metodo è dichiarato.

Vediamo in che maniera una classe eredita un metodo protected e in che modo si
può richiamare
 
ABSTRACT
LE CLASSI ASTRATTE NON VENGONO ISTANZIATE
E’ logico pensare che, ora che abbiamo delle specializzazioni, non andremo più a
creare un oggetto di classe Persona poiché, nella nostra scuola, una persona è o
docente o studente.

Quindi, ciò che ci rimane della classe Persona è solo la descrizione. Perciò possiamo
definire la classe Persona come astratta. 

In questo modo, ogni volta che creeremo un nuovo oggetto nel nostro programma,
questo deve essere un docente o uno studente. Non potrà essere una semplice
persona.
Ma cosa succede se una classe astratta implementa un metodo?
Facciamo un esempio. Ci sembra logico che le persone, a prescindere che siano
docenti o studenti o avvocati o qualsiasi altra sottocategoria, si possano presentare.
Ovviamente, ogni persona lo farà in maniera diversa. Quindi nella classe persona
dichiariamo un metodo astratto ( che non verrà mai richiamato ), e in ogni classe che
lo eredita, andiamo a specificare come si presenterà un oggetto di quella classe

A riga 15 abbiamo dichiarato un metodo astratto perché, dato che nessun oggetto di
classe persona verrà istanziato, il metodo non verrà mai chiamato da un oggetto di
quella classe.

Ora dobbiamo specificare come si presenteranno gli oggetti delle classi che
estendono la classe Persona
Iniziamo dal docente

Come possiamo vedere, il docente implementa il metodo presentati, specificando


come si presenta.

Passiamo allo studente


 

Anche la classe studente implementa il metodo presentati e lo implementa in


maniera diversa rispetto al docente

Quindi abbiamo dichiarato che tutte le persone si possono presentare ma, in base
alla categoria a cui appartengono, lo fanno in maniera diversa.
 

TRAIT

Abbiamo visto che una classe che viene estesa da un’altra classe, può specificare un
metodo della classe genitore. 
Ma cosa succede quando il metodo si può astrarre a un livello ancora più alto?
Quando un comportamento può essere adottato da classi che non hanno alcun
legame?

In questo caso, i trait vengono in nostro aiuto.


Cos’è un trait? 
Un trait è un comportamento che può essere utilizzato da tutte le classi in cui la
includiamo.

Ad esempio, immaginiamo di avere una classe Persona e una classe Animale.


Nessuna delle due è in relazione poiché una persona non può, nella nostra logica,
derivare da un animale.
No, non sono un creazionista.
Una delle azioni che accomuna questi due esseri viventi è mangiare. Entrami si
nutrono per sopravvivere. Quindi possiamo creare un trait che indichi che le due
classi si nutrono.
Un trait contiene una funzione che può essere richiamata da tutti gli oggetti delle
classi che usano quel trait.
 
OBJECT COMPOSITION E DEPENDENCY INJECTION

Questi due concetti ci permettono di astrarre ad un livello superiore la costruzione


delle nostre classi e quindi dei nostri oggetti.

ESEMPIO: LA MACCHINA DI BATMAN

Vogliamo costruire la macchina di Batman e dividerla in due parti:


una parte anteriore che si occuperà dell’attacco
una parte posteriore che si occuperà del movimento 

Come sappiamo tutti, la macchina di Batman ha la possibilità di utilizzare diversi


componenti.
Ad esempio, la parte anteriore può attaccare usando il lanciarazzi o il lanciafiamme e
la parte posteriore si può spostare con le ruote o con i cingoli.
Sfruttiamo questa particolarità per comporre la macchina di Batman che più ci
piace.

Quindi, come prima cosa, realizziamo le due parti della macchina di Batman
. La parte anteriore, come abbiamo detto prima, servirà per attaccare. Quindi,
rimaniamo sul semplice e diciamo che la parte anteriore può solo attaccare

Sia la classe che la funzione al suo interno le dichiariamo abstract perché non
decideremo di utilizzare la funzione attack tramite la parte anteriore ma tramite una
sua specializzazione: lanciarazzi o lanciafiamme.

. La parte posteriore servirà per spostarsi. Come prima, diciamo che la


responsabilità della parte posteriore è muoversi. Non ci muoveremo mai
istanziando una parte posteriore ma una sua specializzazione. Quindi dichiariamo
classe e funzione come astratte
 

Per spostarci, useremo le ruote o i cingoli.

Una volta create le due classi astratte, creiamo le specializzazioni.


Quali sono le specializzazioni?

Parte anteriore ( specializzazioni che permettono l’attacco


):
lanciarazzi
lanciafiamme
 

Questa classe specifica che attaccherà con il lanciarazzi ed estende Parte


anteriore
 

Questa classe specifica che utilizza il lanciafiamme per attaccare

Parte posteriore ( specializzazioni che permettono il


movimento ):
ruote
cingoli
 

Questa classe specifica che la macchina si muove con le ruote


 

Questa classe specifica che la macchina si muove con i cingoli

Una volta creati i componenti, possiamo creare la classe della macchina di batman e
istruirla sui componenti che deve utilizzare

Ragioniamo per step

1. creiamo la classe Batman e gli diciamo che sarà


composto da una parte posteriore e una parte anteriore
 

Nella funzione construct abbiamo un esempio di


DEPENDENCY INJECTION.
Ma cosa vuol dire? 
Scrivendo il nome della classe prima del nome della variabile, stiamo dicendo al
costruttore che la variabile che riceverà in ingresso come $parteAnteriore deve
essere per forza di tipo ParteAnteriore e la variabile che riceverà in ingresso come
$partePosteriore dovrà essere per forza di tipo PartePosteriore. 

La funzione construct controllerà il tipo dei parametri in ingresso e costruirà


l’oggetto se e solo se i tipi verranno rispettati.

In questo modo, creiamo una dipendenza tra la classe e i componenti con cui deve
essere creata.

Creiamo la nostra prima macchina di Batman e vediamo


cosa abbiamo
 

Stampando la variabile notiamo che Batman è un oggetto e che le sue due proprietà
parteAnteriore e partePosteriore, sono a loro volta oggetti e le loro classi sono
LanciaRazzi e Ruote.

Ora istruiamo la classe su ciò che può fare: muoversi ed


attaccare
 

Nella nostra classe, aggiungiamo due metodi: il metodo per attaccare e il metodo per
muoversi.

Ragioniamo un po’. 
parteAnteriore e partePosteriore non sono due sempili properties della classe
Batman. Sono due oggetti. Questi due oggetti appartengono a delle classi che
implementano dei metodi.
Quindi, scrivendo $this→partePosteriore→move(); io accedo al metodo move
presente nella classe partePosteriore. 

Dato che l’attributo partePosteriore del nostro batman è di tipo Ruote, quando
richiamiamo la funzione muoviti, questa richiamerà la funzione move della classe
Ruote e stamperà 
“Avanzo velocemente”.
Dato che l’attributo parteAnteriore del nostro batman è di tipo LanciaRazzi, quando
richiamiamo la funzione attacca, questa richiamerà la funzione attack della classe
LanciaRazzi e stamperà “ti attacco con i razzi”

Vediamo in codice
 
Ora possiamo creare tanti batman combinando vari tipi di attacchi e vari tipi di
movimento

Vediamo qualche esempio


a

Potrebbero piacerti anche