Lärande OOP i PHP ASAP!

PHP är så mycket mer än ett skriptspråk. Det är ett fullfjädrad språk som kan bygga mycket komplexa applikationer. Genom att utnyttja den fullständiga kraften i objektorienterad programmering kan du minska hur lång tid du spenderar kodning och använda den för att bygga bättre webbplatser. Denna handledning visar dig hur.




Vad är OOP?

OOP står för Object Oriented Programming. OOP är ett programmeringsparadigm där du skapar "objekt" för att arbeta med. Dessa objekt kan sedan skräddarsys efter dina specifika behov, för att betjäna olika typer av applikationer samtidigt som samma kodbas upprätthålls. Ganska användbart faktiskt.

Vad är ett objekt?

Ett objekt är helt enkelt en kopia eller ett exempel på en "klass". En klass kan definieras som en "svart ruta" där vi skapar våra objekt och åtkomst till dess attribut (variabler) och metoder (funktioner). Den vanligaste analogi som ges när du förklarar klasser och OOP är hur du kör bil: i grunden har du 2 eller 3 pedaler, en växellåda och ett ratt. Du behöver inte (och förmodligen inte vill) veta hur bilen fungerar när du trycker på pedalerna. Du vill bara att din bil ska gå fram och tillbaka, vänster och höger. Och OOP är just det. Du behöver inte veta hur metoderna i en klass fungerar (om du inte implementerade det själv), precis vad de gör. OOP är också användbart om du har ett stort antal objekt av samma typ i ett system: du måste bara skapa objekten och sedan manipulera dem på samma sätt utan att skriva om någon kod. Dessutom kan ett objekt behålla det tillstånd (variabla värden och sålunda) under hela programmets utförande.


Implementeringen av "Car" är dold från oss, men vi kan använda sin fulla kapacitet.

OOP i PHP

PHP 5 (även om de flesta av idéerna i den här artikeln gäller även PHP 4) har bra stöd för objektorienterad programmering genom att skapa enkel klass skapande. PHP ger varje paradigm andra "sanna" OOP-språk implementera (Python och JAVA, till exempel), som arv, polymorfi och inkapsling.

Arv

Grundidén bakom arv är att liknande föremål delar gemensamma egenskaper. Så genom att skapa en "generisk" klass kan vi få en ritning för att bygga våra efterföljande klasser på. Föreställ dig, om du vill, en bils egenskaper: färg, antal hjul, hästkrafter, antal platser etc. Med denna mall kan vi ytterligare specialisera våra bilar genom att utvidga den här klassen: skapa en racerbil med en "nitro" -egenskap, eller en lastbil som har en "trailer" -egenskap. Bottom line är: skapa en mer generisk klass som innehåller de flesta av de gemensamma attributen och du kommer att ha mycket mindre arbete som definierar andra objekt bara lite annorlunda. Istället för att skriva om hela koden förlänger du bara dess egenskaper, vilket sparar mycket tid i processen.


Erfarenhetsdiagram för våra bilklasser.

inkapsling

Som tidigare förklarats är en av de främsta fördelarna med att använda objekt att vi inte behöver avslöja alla dess medlemmar (attribut eller funktioner); bara de nödvändiga gränssnitten för att arbeta med det. Detaljer som inte är användbara för användningen av dessa objekt borde gömmas från resten av objekten. Detta är vad som kallas inkapsling.

Synlighetsnivåer

  • offentlig: innebär att en klassmedlem är synlig och användbar / modifierbar av alla
  • privat: innebär att en klassmedlem endast är användbar / modifierbar av klassen själv
  • skyddad: innebär att en klassmedlem endast är användbar / modifierbar av klassen själv och eventuella underklasser

OBS! Som standard, i PHP, är en klassmedlem offentlig, om inte deklareras privat eller skyddad. Kolla in ett exempel här.

polymorfism

Polymorfism är en OOP-egenskap som tillåter programmeraren att tilldela en annan mening eller användning till något i olika sammanhang, särskilt för att en klassmedlem ska kunna utföra olika uppgifter beroende på det sammanhang som det användes. Föreställ dig att du har en personklass och två underklasser av person: japanska och amerikanska. Båda implementerar en funktion som heter talk (), men med olika språk och sociala sammanhang. Och medan båda är i grunden Människor (som de härleder från klassen Person), är deras genomförande av funktionstalet () mycket annorlunda. Så du har i grund och botten två objekt av klassen Person där funktionen talk () fungerar annorlunda.

Att få våra händer smutsiga

Ok, nu för den verkliga åtgärden. Vi kommer att skapa en enkel klass för hantering av bildhantering och informationsutvinning. Under hela denna handledning kommer jag att anta att du har en grundläggande förståelse för PHP (variabler, skapa funktioner, arbeta med kontrollflödesanalyser och loopar). Att läsa GD PHP-handboken tar bort eventuella tvivel om bildhanteringsfunktioner.

Steg 1: Skapa vår klass

Vi börjar med att definiera vår klass:

Detta berättar bara om PHP vi kommer att börja definiera en ny klass med namnet "Image". Nu ska vi definiera klasskonstruktören. En konstruktör är helt enkelt den funktion som heter när man skapar ett nytt objekt. I PHP 5 kan detta uppnås med två olika metoder: skapa en offentlig funktion med exakt samma namn på klassen (PHP 4 och på) eller genom att skapa en funktion som heter "__construct ()" (endast PHP 5):

Steg 2: Skapa klasskonstruktorn

Följande två kodstycken gör exakt samma sak:

OBS! En klasskonstruktor är alltid offentlig.

Klasskonstruktörer bör användas för att säkerställa att det skapade objektet har en minimal mängd data att arbeta med; i vårt fall den önskade bilden.

Som sådan är det första vi behöver göra att läsa bilden, oavsett vad den är typ kan vara. För närvarande stöder GD-biblioteket ett antal bildtyper, som jpg, png, gif, bmp och andra; vi måste bara läsa bilden och bestämma den är typ.

Så vad har vi gjort? För att öppna bilden så enkelt som möjligt använder vi GD: s funktion imagecreatefromstring (som tar en binär sträng data som input), istället för imagecreatefromjpeg, imagecreatefrompng eller imagecreatefromgif, till exempel.

Så försöker vi öppna en bildfil och tilldela den filpekaren till $ fp, och, vid fel, avsluta programmets körning.

$ fp = fopen ($ filnamn, 'rb') eller dö ("Bild" $ filnamn "hittades inte!");

Därefter skapar vi en tom sträng för att hålla våra data ...

$ buf = ";

... och läs hela filen, sammanfatta data läs med vårt nyskapade sträng innehåll.

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

Nu måste vi bara skapa vår bild med de data vi just läste ...

imagecreatefromstring ($ buf);

... och skapa ett objekt för att använda alla dessa funktioner.

$ image = ny bild ("image.png");

OBS! Jpg, png, gif och de flesta bildfiler måste läsas i binärt läge, varför "rb" passerade som det andra argumentet för fopen-funktionen. "r" betyder skrivskyddad och "b" betyder binär.

Steg 3: Definiera klassattribut och metoder

I sin nuvarande form är vår klass inte särskilt användbar. Så vi lägger till några attribut och metoder för att göra det mer användbart. Så börjar vi med 1: definiera vissa interna variabler (notera den "privata" synlighetsdeklarationen före varje variabel)

image = imagecreatefromstring ($ buf); // extra bildinformation $ info = getimagesize ($ filnamn); $ this-> width = $ info [0]; $ this-> height = $ info [1]; $ this-> mimetype = $ info ['mime'];  $ image = ny bild ("image.png"); // Om allt gick bra har vi nu läst bilden?>

Och 2: a metod för att visa bilden.

mimetyp "); växla ($ this-> mimetype) case 'image / jpeg': imagejpeg ($ this-> bild); break; case 'image / png': imagepng ($ this-> bild); fallet 'image / gif': imagegif ($ this-> bild); break; // exit; $ image = ny bild ($ _ GET ['image']); // Om allt gick bra har vi nu läst bilden?>

I detta steg skapade vi bara några klassattribut (bild, bredd, höjd och mimetyp) för att hålla objektets data. Sedan gjorde vi några ändringar för att tilldela den skapade bilden till vårt klassattribut $ image...

$ this-> image = imagecreatefromstring ($ buf)

... och extraherade bildens information till våra återstående klassvariabler (läs dokumentationen på getimagesize för att förstå hur bildinformationen läses):

// extra bildinformation $ info = getimagesize ($ filnamn); $ this-> width = $ info [0]; $ this-> height = $ info [1]; $ this-> mimetype = $ info ['mime'];

Därefter skapade vi en funktion som matar ut bilden till webbläsaren genom att definiera lämpliga rubriker (läs mer på http-rubriker här) och använd lämplig funktion (med omkopplingsdeklarationen) för att mata ut bilden baserat på den ursprungliga bildmimetypen (för denna handledning vi stöder bara jpg, png och gif men som jag sa tidigare stöder GD en mängd andra format. Läs php dokumentationen för mer).

Så vad är det här "$ detta" grejer där inne? "$ this", i PHP, hänvisar till klassen själv, och det brukar peka på klassattribut eller funktioner. Som sådan, $ this-> bildpunkter till klassattributet namnet "$ image" och $ this-> image = ... ändrar värdet av klassattributet. Om du skulle skriva $ image = ... skulle du bara skapa en ny lokal variabel som heter "$ image", tillgänglig exklusivt under hela tiden. Detta är en av de viktigaste sakerna att uppmärksamma när man skapar klasser i PHP.


Vår inte mycket användbar (ännu!) Visningsmetod.

Steg 4: Definiera vår "Miniatyr" underklass

Just nu är vår klass inte särskilt användbar. Visst, vi kan läsa vår bild och visa den, men det är det. Vi ska nu skapa en underklass för att skapa våra miniatyrbilder. (Vi behöver verkligen inte skapa en underklass, men vi kommer för tutorialets skull att visa arv och polymorfism). Så, för arvet att fungera ordentligt, behöver vi ändra definitionen av vår superklass något (Bild). Vi behöver bara ändra synligheten för våra klassvariabler från "privat" till "skyddad". Och nu ska vi skapa konstruktören i vår underklass.

bild, 0, 0, 0, 0, $ bredd, $ höjd, $ this-> bredd, $ this-> height); $ this-> image = $ thumb; ?>

Så vad gör vi här exakt? Vi skapade en ny klass, härledd från vårt ursprungliga, vilket innebär att vi kan få tillgång till alla dess offentliga och skyddade attribut och metoder. Vi kallar superklasskonstruktören, ansvarig för att läsa bilden och extrahera sin information. Underklasskonstruktören ringer inte sin superklasskonstruktor så vi måste kalla det explicit.

Nu skapar vi en ny bild för vår miniatyrbild, med bredden och höjden gått:

$ thumb = imagecreatetruecolor ($ bredd, $ höjd);

Resample (resize) originalbilden till den nya, för att skapa miniatyrbilden:

imagecopyresampled ($ thumb, $ this-> bild, 0, 0, 0, 0, $ bredd, $ höjd, $ this-> width, $ this-> height);

Och ändå ändra originalbilden så att den innehåller miniatyrbilden istället för bilden i full storlek:

$ this-> image = $ thumb;

Och gissa vad? Vi behöver inte verkligen skriva en ny funktion för att visa miniatyren eftersom samma princip gäller, oavsett om du visar en fullstor bild eller en miniatyrbild. Det är trots allt fortfarande en bild! Så vi behöver bara ringa vår display () -funktion, definierad i superklassen, och vi är klara!


Vår färdiga klass och respektive underklass.

Och det avslutar vår handledning. Som en övning föreslår jag att du implementerar en funktion för att spara de genererade miniatyrerna till disken istället för att utföra den på flygningen (Var ska du implementera den funktionen? I super eller underklass?). Lycka till och kolla rutan som anges för ett exempelbruk och hela klasserna som utvecklats här (du måste ha en PHP-driven server för att testa den).

  • Prenumerera på NETTUTS RSS-flödet för fler dagliga webbutvecklingstoppar och artiklar.