Imparare l'OOP in PHP al più presto!

PHP è molto più di un linguaggio di scripting. È un linguaggio completo in grado di costruire applicazioni molto complesse. Sfruttando tutta la potenza della programmazione orientata agli oggetti, puoi ridurre la quantità di tempo che trascorri nella codifica e utilizzarla per creare siti web migliori. Questo tutorial ti mostrerà come.




Cos'è OOP?

OOP sta per Object Oriented PROGRAMMAZIONE. OOP è un paradigma di programmazione in cui crei "oggetti" con cui lavorare. Questi oggetti possono quindi essere adattati alle tue esigenze specifiche, per servire diversi tipi di applicazioni mantenendo la stessa base di codice. Abbastanza utile davvero.

Cos'è un oggetto?

Un oggetto è semplicemente una copia o un'istanza di una "classe". Una classe può essere definita come una "scatola nera" da dove creiamo i nostri oggetti e accediamo ai suoi attributi (variabili) e metodi (funzioni). L'analogia più comune data quando si spiegano le classi e l'OOP è come si guida un'auto: in pratica si hanno 2 o 3 pedali, una leva del cambio e un volante. Non hai bisogno (e probabilmente non vuoi) di sapere come funziona la macchina quando premi i pedali. Vuoi solo che la tua auto vada avanti e indietro, sinistra e destra. E OOP è esattamente questo. Non è necessario sapere come funzionano i metodi di una classe (se non l'hai implementato tu stesso), solo quello che fanno. OOP è anche utile se hai un gran numero di oggetti dello stesso tipo in un sistema: devi solo creare gli oggetti e poi manipolarli tutti allo stesso modo, senza riscrivere alcun codice. Inoltre, un oggetto è in grado di mantenere il suo stato (valori variabili e così via) durante l'esecuzione del programma.


L'implementazione di "Car" è nascosta a noi, tuttavia possiamo utilizzare tutte le sue capacità.

OOP in PHP

PHP 5 (anche se la maggior parte delle idee in questo articolo si applicano anche a PHP 4) ha un grande supporto per la programmazione orientata agli oggetti, fornendo una facile creazione di classi. PHP fornisce tutti i paradigmi implementati da altri linguaggi OOP "veri" (ad esempio Python e JAVA), come l'ereditarietà, il polimorfismo e l'incapsulamento.

Eredità

L'idea di base dietro l'ereditarietà è che oggetti simili condividono proprietà comuni. Quindi, creando una classe "generica", possiamo avere un progetto per costruire le nostre lezioni successive. Immaginate, se volete, le proprietà di un'auto: colore, numero di ruote, potenza, numero di posti, ecc. Avendo questo modello possiamo ulteriormente specializzare le nostre auto estendendo questa classe: creando un'auto da corsa che abbia una proprietà "nitro", o un camion che ha una proprietà "trailer". La linea di fondo è: creare una classe più generica che contiene la maggior parte degli attributi comuni e si avrà molto meno lavoro definendo altri oggetti solo leggermente diversi. Invece di riscrivere l'intero codice, è sufficiente estenderne le proprietà, risparmiando un sacco di tempo nel processo.


Diagramma di successione per le nostre classi di auto.

incapsulamento

Come precedentemente spiegato, uno dei principali vantaggi dell'utilizzo di oggetti è che non è necessario rivelare tutti i suoi membri (attributi o funzioni); solo le interfacce necessarie per lavorarci. I dettagli non utili per l'uso di questi oggetti dovrebbero essere nascosti dal resto degli oggetti. Questo è ciò che viene definito come incapsulamento.

Livelli di visibilità

  • pubblico: significa che un membro della classe è visibile e utilizzabile / modificabile da tutti
  • privato: significa che un membro della classe è utilizzabile / modificabile solo dalla classe stessa
  • protetta: significa che un membro della classe è utilizzabile / modificabile solo dalla classe stessa e da eventuali sottoclassi

NOTA: per impostazione predefinita, in PHP, un membro della classe è pubblico a meno che non sia dichiarato privato o protetto. Guarda un esempio qui.

Polimorfismo

Il polimorfismo è una caratteristica OOP che consente al programmatore di assegnare un significato o un utilizzo diverso a qualcosa in contesti diversi, in particolare per consentire a un membro della classe di eseguire compiti diversi a seconda del contesto in cui è stato utilizzato. Immagina di avere una classe Persona e due sottoclassi di Persona: giapponese e americana. Entrambi implementano una funzione denominata talk (), ma con lingue e contesti sociali diversi. E mentre entrambi sono fondamentalmente persone (come derivano dalla classe Person), la loro implementazione della funzione talk () è molto diversa. Quindi in pratica hai due oggetti della classe Persona in cui la funzione talk () funziona diversamente.

Sporcarsi le mani

Ok, ora per la vera azione. Creeremo una semplice classe per gestire la manipolazione delle immagini e l'estrazione delle informazioni. Per la durata di questo tutorial assumerò che tu abbia una conoscenza di base di PHP (variabili, creazione di funzioni, utilizzo di istruzioni e loop di controllo del flusso). Leggendo il manuale di GD PHP rimuoverai tutti i dubbi che potresti avere sulle funzioni di gestione delle immagini.

Passaggio 1: creazione della nostra classe

Iniziamo definendo la nostra classe:

Questo dice solo a PHP che inizieremo a definire una nuova classe, chiamata "Immagine". Ora definiremo il costruttore della classe. Un costruttore è semplicemente la funzione che viene chiamata quando si crea un nuovo oggetto. In PHP 5 questo può essere ottenuto con due metodi diversi: creare una funzione pubblica con lo stesso nome della classe (PHP 4 e on) o creando una funzione chiamata "__construct ()" (solo PHP 5):

Passaggio 2: creazione del costruttore della classe

I seguenti due pezzi di codice fanno esattamente la stessa cosa:

NOTA: un costruttore di classi è sempre pubblico.

I costruttori di classi dovrebbero essere utilizzati per garantire che l'oggetto creato abbia una quantità minima di dati con cui lavorare; nel nostro caso, l'immagine desiderata.

In quanto tale, la prima cosa che dobbiamo fare è leggere l'immagine, qualunque sia il suo tipo. Attualmente, la libreria GD supporta un numero di tipi di immagine, come jpg, png, gif, bmp e altri; dobbiamo solo leggere l'immagine e determinare il suo tipo.

Quindi cosa abbiamo fatto? Per aprire l'immagine nel modo più semplice possibile, useremo la funzione GD imagecreatefromstring (che prende una stringa binaria di dati come input), invece di imagecreatefromjpeg, imagecreatefrompng o imagecreatefromgif, ad esempio.

Quindi proviamo ad aprire un file immagine e assegnarlo al puntatore del file $ fp, e, in caso di fallimento, interrompere l'esecuzione del programma.

$ fp = fopen ($ filename, 'rb') o die ("Immagine '$ nomefile' non trovato!");

Successivamente, creiamo una stringa vuota per contenere i nostri dati ...

$ buf = ";

... e leggi l'intero file, concatenando i dati letti con il nostro contenuto di stringhe appena creato.

while (! feof ($ fp)) $ buf. = fgets ($ fp, 4096);

Ora dobbiamo solo creare la nostra immagine usando i dati che abbiamo appena letto ...

imagecreatefromstring ($ buf);

... e creare un oggetto per utilizzare tutte queste funzioni.

$ image = new Image ("image.png");

NOTA: jpg, png, gif e la maggior parte dei file di immagine devono essere letti in modalità binaria, quindi "rb" passa come secondo argomento della funzione fopen. "r" significa sola lettura e "b" significa binario.

Passaggio 3: definizione degli attributi e dei metodi della classe

Nella sua forma attuale la nostra classe non è molto utile. Quindi aggiungeremo alcuni attributi e metodi per renderlo più utile. Quindi inizieremo da 1: definendo alcune variabili interne (nota la dichiarazione di visibilità "privata" prima di ogni variabile)

image = imagecreatefromstring ($ buf); // estrae le informazioni sull'immagine $ info = getimagesize ($ nomefile); $ this-> width = $ info [0]; $ this-> height = $ info [1]; $ this-> mimetype = $ info ['mime'];  $ image = new Image ("image.png"); // Se tutto è andato bene, ora abbiamo letto l'immagine?>

E 2: un metodo per visualizzare l'immagine.

mimetype "); switch ($ this-> mimetype) case 'image / jpeg': imagejpeg ($ this-> image); break; case 'image / png': imagepng ($ this-> image); break; case 'image / gif': imagegif ($ this-> image); break; // exit; $ image = new Image ($ _ OTTIENI ['image']); // Se tutto è andato bene, ora abbiamo letto l'immagine?>

In questo passaggio abbiamo appena creato alcuni attributi di classe (immagine, larghezza, altezza e mimetype) per contenere i dati dell'oggetto. Quindi abbiamo apportato alcune modifiche per assegnare l'immagine creata al nostro attributo di classe $ image...

$ this-> image = imagecreatefromstring ($ buf)

... ed estrae le informazioni dell'immagine sulle nostre rimanenti variabili di classe (leggi la documentazione su getimagesize per comprendere appieno come vengono letti i dati dell'immagine):

// estrae le informazioni sull'immagine $ info = getimagesize ($ nomefile); $ this-> width = $ info [0]; $ this-> height = $ info [1]; $ this-> mimetype = $ info ['mime'];

Successivamente abbiamo creato una funzione che restituisce l'immagine al browser definendo le intestazioni appropriate (leggi di più sulle intestazioni http qui) e utilizzando la funzione appropriata (con l'istruzione switch) per emettere l'immagine in base al mimetype dell'immagine originale (per questo tutorial supporteremo solo jpg, png e gif ma, come ho detto prima, GD supporta una moltitudine di altri formati.Ulteriori la documentazione php per ulteriori informazioni.

Allora, cos'è questa roba "$ this"? "$ this", in PHP, si riferisce alla classe stessa, ed è usato per indicare attributi o funzioni di classe. In quanto tale, $ this-> image punta all'attributo class denominato "$ image" e $ this-> image = ... cambia il valore dell'attributo class. Se dovessi scrivere $ image = ... dovresti semplicemente creare una nuova variabile locale chiamata "$ image", disponibile esclusivamente per la durata della funzione. Questa è una delle cose principali a cui prestare attenzione quando si creano classi in PHP.


Il nostro metodo di visualizzazione non molto utile (ancora!).

Passaggio 4: definizione della sottoclasse "Miniatura"

In questo momento la nostra classe non è molto utile. Certo, possiamo leggere la nostra immagine e mostrarla, ma il gioco è fatto. Ora creeremo una sottoclasse per creare le nostre miniature. (Non abbiamo davvero bisogno di creare una sottoclasse, ma lo faremo per il tutorial, per dimostrare l'ereditarietà e il polimorfismo). Quindi, affinché l'ereditarietà funzioni correttamente, dobbiamo cambiare leggermente la definizione della nostra super-classe (Immagine). Abbiamo solo bisogno di cambiare la visibilità delle nostre variabili di classe da "privato" a "protetto". E ora creeremo il costruttore della nostra sottoclasse.

immagine, 0, 0, 0, 0, $ larghezza, $ altezza, $ this-> width, $ this-> height); $ this-> image = $ thumb; ?>

Quindi, cosa stiamo facendo esattamente qui? Abbiamo creato una nuova classe, derivata dal nostro originale, il che significa che possiamo accedere a tutti i suoi attributi e metodi pubblici e protetti. Chiamiamo il costruttore super-class, responsabile della lettura dell'immagine e dell'estrazione delle sue informazioni. Il costruttore della sottoclasse non chiama il costruttore della superclasse, quindi dobbiamo chiamarlo esplicitamente.

Ora creiamo una nuova immagine per la nostra miniatura, con la larghezza e l'altezza passate:

$ thumb = imagecreatetruecolor ($ width, $ height);

Ricampiona (ridimensiona) l'immagine originale nella nuova, per creare la miniatura:

imagecopyresampled ($ thumb, $ this-> image, 0, 0, 0, 0, $ width, $ height, $ this-> width, $ this-> height);

E infine modificare l'immagine originale per contenere l'anteprima anziché l'immagine a dimensione intera:

$ this-> image = $ thumb;

E indovina cosa? Non è necessario scrivere una nuova funzione per visualizzare la miniatura perché si applica lo stesso principio, indipendentemente dal fatto che si visualizzi un'immagine a dimensione intera o una miniatura. Dopotutto, è ancora un'immagine! Quindi abbiamo solo bisogno di chiamare la nostra funzione display (), definita nella super-classe, e abbiamo finito!


La nostra classe completa e la rispettiva sottoclasse.

E questo conclude il nostro tutorial. Come esercizio I, suggerisco di implementare una funzione per salvare le miniature generate su disco invece di produrle al volo (dove dovresti implementare quella funzione? Nella super o nella sottoclasse?). Buona fortuna e controlla lo zip fornito per un esempio di utilizzo e le classi complete sviluppate qui (è necessario disporre di un server PHP per testarlo).

  • Iscriviti al feed RSS di NETTUTS per ulteriori tuts e articoli di sviluppo web giornalieri.