Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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.
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.
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.
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
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
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.
Es
. 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.
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, 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
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
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.
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.
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.
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
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_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’
User functions
Le user functions, manco a dirlo, sono le funzioni create dall’utente.
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 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.
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?
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.
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.
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.
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
. 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.
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
Per indicare che una classe che stiamo descrivendo estende un’altra classe già
esistente, si utilizza la keyword extends nome_classe_che_viene_estesa
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.
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
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?
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.
Una volta creati i componenti, possiamo creare la classe della macchina di batman e
istruirla sui componenti che deve utilizzare
In questo modo, creiamo una dipendenza tra la classe e i componenti con cui deve
essere creata.
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.
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