provkapitel för boken Webbserverprogrammering 1

Transcription

provkapitel för boken Webbserverprogrammering 1
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
FÖRLAGETS FÖRORD
Detta är ett smakprov av Läroboken Webbserverprogrammering 1. Boken är anpassad efter
gymnasieskolans kursplan GY2011 för kursen Webbutveckling 1 med kurskod WEBWEB01.
Boken är skriven av Lars Gunther. Erfaren gymnasielärare inom bl.a. webbutveckling och
programmering. Boken är utgiven av Thelin Läromedel. Boken finns även tillgänglig för läsning
via internet via Skolportalen eBooks.
Boken bygger vidare utifrån innehållet i boken Webbutveckling 1. Om du inte redan har läst den,
så förutsätts att du inhämtat motsvarande kunskaper på annat håll.
Om du käre läsare skulle hitta något i boken som du inte tycker stämmer eller om du saknar
någon viktig del så får du gärna meddela detta till oss. Vi är oerhört tacksamma för alla
kommentarer och tips. Det går bra att e-posta till [email protected]
Eventuella uppdateringar och rättelser till boken som tillkommit efter denna upplagas tryckning
finns att ladda hem på Skolportalen, www.skolportalen.se.
Till boken hör en Arbetsbok med praktiska övningar. Gör övningarna i arbetsboken efter varje
kapitel i denna bok.
En lärarhandledning kommer också att utkomma. I denna finns värdefulla tips till läraren.
Thelin Läromedel och Lars Gunther, juni 2013.
Detta ”smakprov” innehåller en preliminär planering av hela bokens innehåll. Utifrån den
respons vi får och vilka begränsninga som kan dyka upp i form av sidantal och liknande, så
kan den planen revideras. Speciellt gäller det alla underrubriker
Samtliga varumärken som förekommer i boken tillhör innehavaren av varumärket.
OBSERVERA ATT ALL KOPIERING ELLER ANNAT MÅNGFALDIGANDE AV DENNA BOK ELLER DELAR
AV DEN ÄR FÖRBJUDET ENLIGT LAG.
THELIN LÄROMEDEL, LIDKÖPING
Tel. 0510-66100, www.skolportalen.se
Första upplagan, utskriven 2013-06-17
Beställningsnummer J200 4550
Tryckeri: JustNu
ISBN: 978-91-7379-241-7
© THELIN LÄROMEDEL & LARS GUNTHER 2013
1
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
FÖRFATTARENS FÖRORD
Det här är boken jag själv hade behövt läsa när jag började programmera för webben. Jag
gjorde nämligen alla tänkbara misstag.
1. Jag skapade invecklad och svårläst grötkod.
2. Jag skapade system som var vidöppna för olika slags attacker.
3. Jag byggde system vars funktion berodde på tekniken och tvingade användarna att
anpassa sig efter den, i stället för tvärtom.
Detta berodde inte på att jag inte lyssnade på råd eller läste böcker i ämnet. Tvärtom så
berodde det på just att jag följde dåliga råd. Jag fick inte redan från början lära mig vilka råd
som var värda att lyssnas till och vilka råd som borde förkastas. Jag lärde mig till en början bara
hur PHP fungerade rent språkligt, inte så mycket om sammanhanget där programmen körs.
Detta är en bok om webbserverprogrammering på grundnivå. Boken är anpassad efter
gymnasieskolans kursplan GY2011 för kursen Webbserverprogrammering 1 i ämnet
Webbteknik, men kan också användas som första material på högskolan eller för egna studier.
Jag som skriver boken har varit ämnesexpert åt Skolverket när kursplanerna i webbteknik tagits
fram. Dessutom är eller har varit jag aktiv inom flera organisationer som ägnar sig åt
webbutveckling och speciellt undervisning i ämnet
Till boken kommer att höra en arbetsbok och en lärarhandledning, samt instruktionsfilmer i
videoform. Dessa kan nås på adressen http://webbteknik.nu/
Lödöse 2013
Lars Gunther
2
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
ATT ANVÄNDA DETTA LÄROMEDEL
Innehållet i detta kapitel är i stort sett identiskt med samma kapitel i boken Webbutveckling 1.
Den här boken är upplagd i kapitel som täcker ett område åt gången. Efter varje kapitel
uppmuntras du göra arbetsuppgifterna som finns i arbetsboken. När du ska göra övningar så
markeras det så här:
Gör nu övningarna i Arbetsboken till kapitel X
Alternativt kan du varva mellan lärobok, videofilmer och arbetsbok enligt den plan som finns på
bokens webbplats.
Arbetsbokens övningar kan vara såväl enkla frågor som besvaras på plats, som större uppgifter
att utföra i datorn. Men även i denna huvudbok kan det finnas praktiska moment som du bör
göra för att få största möjliga utbyte av läromedlet.
Typografiska konventioner
 Källkod är färgmarkerad enligt en konvention som förklaras i avsnitt xyz.1
 Källkod som står mot gul bakgrund är att betrakta som föredömlig, medan källkod som
står mot ljus orange bakgrund är mindre bra.
 Särskilt intressanta delar markeras med fetstil och kursiveras.
 Facktermer markeras med rödbrun färg och fet kursiverad stil.
 Text i varningsrutor visas med kursiv text i en blå ruta.
 Text i tipsrutor eller förslag på fördjupningsläsning
visas i en grön ruta.
Text i en varningsruta
Text i en tipsruta
 Namn på organisationer, personer, allmänna nyckelord, program, filnamn och objekt i
datorn markeras med blå text.
1
Ingen färgkodning i dessa provkapitel.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
3
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Många gånger kan man inte hitta bra hjälp om webbutveckling på svenska, utan måste söka på
engelska. Därför kommer alla nyckelord att skrivas på båda språken, utom då motsvarande ord
saknas på svenska eller när översättningen är självklar.
Webbplats
Det finns en webbplats till boken med ytterligare resurser på adressen http://webbteknik.nu/
På den här adressen kommer det läggas upp videofilmer som är anpassade till att vara
komplement till den här boken. När det finns filmer som matchar bokens kapitel, så markeras
det genom att ordet ”video” skrivs vid rubriken.
Lägg märke till att fler filmer kan komma att läggas till efterhand, så kolla gärna webbplatsen när
du läser varje kapitel, oavsett symbolen.
Här kommer också alla länkar från boken att finnas, samt kodexempel och nedladdningar – och
om händelsevis något fel smugit sig in i texten så kommer det finnas rättelser här också.
Till sist: Vad denna bok inte är
(I likhet med boken Webbutveckling 1.)
 Detta är inte en ”kokbok” som ger dig 1-2-3 recept för att bygga en webbsida. Boken vill
ge dig förståelse för vad du sysslar med.
 Detta är inte en referensbok som ger dig kompletta genomgångar kring varje teknik.
Sådant finns på nätet. Den här boken vill hjälpa dig förstå vad det är du läser där.
 Detta är inte din viktigaste kunskapskälla! Det är dina egna experiment och diskussionen
med andra utvecklare. Den här boken vill ge dig en knuff att komma igång att koda, samt
ge dig ord att använda för sådana samtal.
Genom att lära dig facktermer och principer för god praxis, så är det min förhoppning att du
ska kunna lösa praktiska problem genom att söka på nätet eller ställa välformulerade frågor i
diskussionsforum. Det här är en bok som vill hjälpa dig förstå, så att du kan på ett bra sätt
ta till dig information från de många uppslagsbokliknande resurserna som finns på Internet
och kunna avgöra vilka ”recept” som är goda och vilka som är dåliga.
Just för att detta är en lärobok, så kommer somliga resonemang vara förenklade, detaljer och
alternativ hoppas över, etc. Detta är en lärobok, inte teknisk dokumentation.
4
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
INNEHÅLLSFÖRTECKNING
FÖRLAGETS FÖRORD ....................................................................................................................... 1
Författarens förord ......................................................................................................................... 2
Att använda detta läromedel ........................................................................................................... 3
Typografiska konventioner ................................................................................................................... 3
Webbplats ............................................................................................................................................. 4
Till sist: Vad denna bok inte är .............................................................................................................. 4
Innehållsförteckning ....................................................................................................................... 5
Ämnesplan och kursplan ................................................................................................................. 9
Ämne – Webbteknik ............................................................................................................................. 9
Kursplan för Webbutveckling 1........................................................................................................... 10
1 Kom igång med PHP ..................................................................................................................15
1.1
Installation av PHP på Linuxdatorer ..................................................................................... 16
1.2
Installation av PHP på Windows och Mac OS X .................................................................... 17
1.3
Ett första PHP-skript ............................................................................................................. 18
1.4
En komplett webbsida med inslag av PHP............................................................................ 21
1.5
Variabler, enkel- och dubbelfnuttar...................................................................................... 23
1.6
Några korta anmärkningar om PHP som språk (syntax och kompilering) ............................ 24
1.7
OK, hur lär jag mig detta? ..................................................................................................... 26
2 ett par ytterligare exempel ........................................................................................................29
2.1
Visa datum, månad, tid, etc.................................................................................................. 30
2.2
Ett slumpmässigt valt citat.................................................................................................... 31
2.3
Räkna antalet tecken i ett namn och skriv det baklänges .................................................... 32
3 PHP:s historia, versioner, styrkor och svagheter .........................................................................36
4 Att använda PHP som ett mallsystem .........................................................................................39
4.1
Samma sida, men olika innehåll ........................................................................................... 39
4.2
Återanvändning av kod mellan olika sidor............................................................................ 39
5 PHP som programmeringsspråk .................................................................................................40
5.1
Kommentarer sparar tid ....................................................................................................... 40
5.2
Värdetyper ............................................................................................................................ 40
5.3
Variablers namngivning och räckvidd (scope) ...................................................................... 40
5.4
Tilldelning ............................................................................................................................. 40
5.5
Några operatorer .................................................................................................................. 40
5.6
Jämförelser, sant och falskt .................................................................................................. 41
© THELIN LÄROMEDEL & LARS GUNTHER 2013
5
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
5.7
PHPCodeSniffer .....................................................................................................................41
6 Säkerhetstänk ........................................................................................................................... 42
6.1
Problemkällor ........................................................................................................................42
6.2
Principer ................................................................................................................................42
6.3
Filter input – escape output ..................................................................................................42
6.4
Fulkod döljer säkerhetshål – och är svårare att underhålla ..................................................42
7 Strängar .................................................................................................................................... 43
7.1
UTF-8 kräver mb-funktionerna..............................................................................................43
7.2
Verifikation av välformad UTF-8 ............................................................................................43
7.3
Ta bort HTML eller ”eskejpa” den..........................................................................................43
8 Arrayer ..................................................................................................................................... 44
8.1
”Min array är inte lik din array”.............................................................................................44
8.2
Definiera arrayer, lägg till, ändra och ta bort värden ............................................................44
8.3
Använda arrayvärden i textsträngar ......................................................................................44
8.4
Loopa genom arrayer med foreach .......................................................................................44
8.5
Array-liknande strukturer ......................................................................................................44
9 Funktioner i PHP ....................................................................................................................... 45
9.1
En funktions funktion ............................................................................................................45
9.2
Sök i manualen, din funktion finns nog redan där! ...............................................................45
9.3
Hellre returnera än skriva......................................................................................................45
9.4
Dokumentera dina funktioner ...............................................................................................45
9.5
Håll alla definitioner för sig och inkludera dem ....................................................................45
10 Objekt i PHP ............................................................................................................................. 46
10.1
Vad är ett objekt ....................................................................................................................46
10.2
Klasser – objekt av en viss typ ...............................................................................................46
10.3
Statiska metoder ...................................................................................................................46
10.4
OO syntax i PHP kontra andra språk ......................................................................................46
11 Databaser och datalagring ........................................................................................................ 47
11.1
Alternativ ...............................................................................................................................47
11.2
MySQL och MariaDB .............................................................................................................47
11.3
Databaser och databashanterare (DBMS) .............................................................................47
11.4
Tabeller, fält, index, poster, relationer ..................................................................................47
PhpMyAdmin .........................................................................................................................47
11.5
12 Att ansluta till en databas och hämta värden ............................................................................. 51
13 Inloggning och lösenordshantering ............................................................................................ 59
13.1
Vad ska ett autentiseringssystem kunna? .............................................................................59
13.2
Bygga eget eller använda befintligt? .....................................................................................59
6
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
13.3
13.4
Sessioner............................................................................................................................... 59
Inloggning för läxhjälpens administratörer .......................................................................... 59
14 Formulär och PHP ......................................................................................................................60
14.1
Ett första exempel................................................................................................................. 60
14.2
Get och post ......................................................................................................................... 60
14.3
Läs med filter-funktionerna .................................................................................................. 60
14.4
Sätt inte användaren på pottkanten ..................................................................................... 60
14.5
Hantera framgången rätt ...................................................................................................... 60
15 Från formulär till databas ..........................................................................................................61
15.1
Lägga in nya poster ............................................................................................................... 61
15.2
Ändra befintliga poster ......................................................................................................... 61
15.3
Radera poster ....................................................................................................................... 61
16 Skicka mejl med PHP .................................................................................................................62
16.1
SMTP och SMTP-injektion .................................................................................................... 62
16.2
Ett exempel ........................................................................................................................... 62
17 Att ha kul med PHP ....................................................................................................................63
17.1
Snygga URL:er ....................................................................................................................... 63
17.2
Skapa annat än HTML-kod .................................................................................................... 63
17.3
Ajax ....................................................................................................................................... 63
17.4
Webbtjänster – att kommunicera med andra servrar .......................................................... 63
17.5
Att skriva PHP-moduler för befintliga applikationer ............................................................ 63
17.6
Att använda ramverk och klassbibliotek............................................................................... 63
17.7
Internationalisering och lokalisering .................................................................................... 63
18 Infrastruktur för utveckling ........................................................................................................64
18.1
En ”riktig” IDE ....................................................................................................................... 64
18.2
Utvecklingsmaskin, staging server, produktionsserver ........................................................ 64
18.3
Webbhotell ........................................................................................................................... 64
18.4
Projekthantering och dokumentation .................................................................................. 64
INDEX ............................................................................................................................................68
© THELIN LÄROMEDEL & LARS GUNTHER 2013
7
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Plats för anteckningar:
8
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
ÄMNESPLAN OCH KURSPLAN
Ämne – Webbteknik
Webbteknik används för att utveckla och vidareutveckla statiska och dynamiska webbsidor,
webbplatser, webbapplikationer eller andra applikationer där webbtekniker används, till
exempel applikationer för mobiltelefoner. Ämnet webbteknik behandlar tekniska aspekter på
olika slags mediaformat och samspelet mellan beställare, användare, formgivare och utvecklare.
Ämnets syfte
Undervisningen i ämnet webbteknik ska syfta till att eleverna utvecklar färdigheter i att skapa
produkter med hjälp av webbteknik. Eleverna ska ges möjlighet att utveckla kunskaper om olika
webbteknikers konstruktion och funktionalitet samt samspelet mellan olika sorters
applikationslogik. Genom undervisningen ska eleverna ges möjlighet att utveckla produkter som
följer standarder och nationella och internationella riktlinjer för god praxis, användbarhet,
tillgänglighet och säkerhet. Undervisningen ska leda till att eleverna utvecklar kunskaper om
relevanta lagar och andra bestämmelser samt förmåga att göra webbrelaterade etiska
överväganden.
I undervisningen ska eleverna ges möjlighet att utveckla kunskaper om och färdigheter i att
använda utvecklingsverktyg för att producera och kontrollera framställning av den kod som
driver webbplatser eller applikationer. Eleverna ska också ges möjlighet att utveckla färdigheter
i att använda befintliga verktyg för administration av webbservrar och databaser.
Vid utveckling av webbtekniska applikationer arbetar man oftast i projektform, varför
undervisningen ska ge eleverna möjlighet att utveckla kunskaper om projektarbetets olika faser
samt tillfälle att arbeta i projekt.
Undervisningen i ämnet webbteknik ska ge eleverna förutsättningar att utveckla
följande:
1. Kunskaper om internets historia, betydelse, terminologi och funktionalitet.
2. Förmåga att planera, genomföra, dokumentera och utvärdera utvecklingsprojekt för
webbplatser och webbapplikationer eller andra slags applikationer som bygger på
webbtekniker.
3. Kunskaper om de tekniker som används för att bygga webbplatser och
webbapplikationer samt dessa teknikers vidgade roll inom annan mjukvaruutveckling.
4. Kunskaper om tekniker för dynamiska webbplatser.
5. Kunskaper om teckenkodning och förmåga att hantera olika standarder för
teckenkodning.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
9
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
6. Förmåga att bygga webbplatser och webbapplikationer enligt standarder och riktlinjer
för god praxis samt med god tillgänglighet för människor med olika förutsättningar.
7. Kunskaper om applikationsarkitektur, inklusive separation av olika slags logik.
8. Kunskaper om lagar och andra bestämmelser inom området samt förmåga att göra
etiska överväganden och reflektera över integritetsfrågor.
9. Kunskaper om säkerhet och förmåga att identifiera och motarbeta attacker.
Kursplan för Webbserverprogrammering 1
Kurskod: WEBWEB01
Kursen webbserverprogrammering 1 omfattar punkterna 1—2 och 4—9 under rubriken Ämnets
syfte, med särskild betoning på punkterna 2, 4—5 och 9.
Centralt innehåll
Undervisningen i kursen ska behandla följande centrala innehåll:











10
Webbserverns och dynamiska webbplatsers funktionalitet.
Utvecklingsprocessen för ett webbtekniskt projekt: målsättningar, planering,
systemering, kodning, dokumentation och uppföljning.
Dokumentation av utvecklingsprocess och färdig produkt, inklusive kod och
mjukvarugränssnitt.
En översikt över olika lösningar eller språk som finns för att skapa dynamiska
webbplatser.
Grunderna i informationshanteringssystem och ramverk.
Grundfunktionen i ett programmeringsspråk för dynamiska webbplatser.
Datalagring, i relationsdatabas eller med annan teknik.
Teckenkodning: begrepp, standarder och handhavande.
Kodning och dokumentation enligt vedertagen praxis för den teknik som används i
sammanhanget.
Kvalitetssäkring av dynamiska webbapplikationers funktionalitet, säkerhet och
kodkvalitet.
Säkerhet: vanliga attackvektorer mot webbapplikationer och de viktigaste principerna
för att hindra attacker.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Kunskapskrav
Betyget E
Eleven beskriver översiktligt dynamiska webbplatsers och informationshanteringssystems
historia och hur de samspelar med olika tekniker på webben. Dessutom beskriver eleven
översiktligt olika tekniska alternativ som finns för webbserverprogrammering och
informationshantering.
Eleven gör en enkel projektplan för en tänkt produkt. I projektplanen beskriver eleven
översiktligt produktens funktion. Utifrån projektplanen utvecklar eleven i samråd med
handledare produkten, där presentationslogiken i begränsad utsträckning är skild från
produktens övriga logik. I arbetet utvecklar eleven kod som i begränsad utsträckning är läsbar
och kommenterad. Produkten uppvisar enkel funktionalitet med ett språk för webbserverprogrammering och tillhandahåller en enkel lösning för datapersistens mellan sidvisningar. I
arbetet redogör eleven också översiktligt för vanliga problem som beror på felaktigt angiven
teckenkodning i olika applikationer.
Produkten är av tillfredsställande kvalitet och följer etablerad god praxis.
När arbetet är utfört gör eleven en enkel dokumentation av de moment som har utförts samt
utvärderar med enkla omdömen sitt arbete och resultat.
Eleven redogör översiktligt för innehållet i lagar och andra bestämmelser som rör publicering på
webben samt följer dem i sitt arbete. Dessutom identifierar eleven någon attackvektor mot
produkten och vidtar någon enkel åtgärd för att förhindra den.
Eleven använder med viss säkerhet enkel terminologi inom området.
När eleven samråder med handledare bedömer hon eller han med viss säkerhet den egna
förmågan och situationens krav.
Betyget D
Betyget D innebär att kunskapskraven för E och till övervägande del för C är uppfyllda.
Betyget C
Eleven beskriver utförligt dynamiska webbplatsers och informationshanteringssystems historia
och hur de samspelar med olika tekniker på webben. Dessutom beskriver eleven utförligt olika
tekniska alternativ som finns för webbserverprogrammering och informationshantering.
Eleven gör en genomarbetad projektplan för en tänkt produkt. I projektplanen beskriver eleven
utförligt produktens funktion och arkitektur. Utifrån projektplanen utvecklar eleven efter
samråd med handledare produkten, där presentationslogiken är skild från produktens övriga
logik. I arbetet utvecklar eleven kod som följer en given kodningsstandard och är
© THELIN LÄROMEDEL & LARS GUNTHER 2013
11
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
kommenterad. Produkten uppvisar funktionalitet med ett språk för webbserverprogrammering
och tillhandahåller en enkel lösning för permanent datalagring. I arbetet redogör eleven också
utförligt för vanliga problem som beror på felaktigt angiven teckenkodning i olika applikationer
samt väljer och anger lämplig teckenkodning.
Produkten är av tillfredsställande kvalitet och följer etablerad god praxis. Detta kontrollerar
eleven med några tester.
När arbetet är utfört gör eleven en noggrann dokumentation av de moment som har utförts
samt utvärderar med nyanserade omdömen sitt arbete och resultat. I utvärderingen gör eleven
välgrundade reflektioner över hur beslut har tagits i arbetet.
Eleven redogör utförligt för innehållet i lagar och andra bestämmelser som rör publicering på
webben samt följer dem i sitt arbete. Dessutom identifierar eleven några attackvektorer mot
produkten och följer grundläggande principer för att förhindra dem.
Eleven använder med viss säkerhet terminologi inom området.
När eleven samråder med handledare bedömer hon eller han med viss säkerhet den egna
förmågan och situationens krav.
Betyget B
Betyget B innebär att kunskapskraven för C och till övervägande del för A är uppfyllda.
Betyget A
Eleven beskriver utförligt och nyanserat dynamiska webbplatsers och informationshanteringssystems historia och hur de samspelar med olika tekniker på webben. Dessutom beskriver
eleven utförligt och nyanserat olika tekniska alternativ som finns för webbserverprogrammering och informationshantering.
Eleven gör en genomarbetad projektplan för en tänkt produkt. Vid behov reviderar eleven
planen. I projektplanen beskriver eleven utförligt och nyanserat produktens funktion,
arkitektur och mjukvarugränssnitt. Utifrån projektplanen utvecklar eleven efter samråd med
handledare produkten, där presentationslogiken är skild från produktens övriga logik. I arbetet
utvecklar eleven kod som följer en given kodningsstandard och är utförligt kommenterad.
Produkten uppvisar tillräcklig funktionalitet med ett språk för webbserverprogrammering för
att driva en helt databasbaserad webbplats eller en jämförbart avancerad produkt och
tillhandahåller en lösning med viss komplexitet för permanent datalagring. I arbetet redogör
eleven också utförligt och nyanserat för vanliga problem som beror på felaktigt angiven
teckenkodning i olika applikationer, väljer och anger lämplig teckenkodning samt anger hur
enklare problem som relaterar till teckenkodningar hanteras.
12
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Produkten är av god kvalitet och följer etablerad god praxis. Detta kontrollerar eleven både
manuellt och med flera tester.
När arbetet är utfört gör eleven en noggrann och utförlig dokumentation av de moment som
har utförts med koppling till generella principer och testresultat samt utvärderar med
nyanserade omdömen sitt arbete och resultat och ger förslag på hur arbetet kan förbättras. I
utvärderingen gör eleven välgrundade och nyanserade reflektioner över hur beslut har tagits i
arbetet.
Eleven redogör utförligt och nyanserat för innehållet i lagar och andra bestämmelser som rör
publicering på webben samt följer dem i sitt arbete. Dessutom identifierar eleven flera
attackvektorer mot produkten och följer grundläggande principer för att förhindra dem.
Eleven använder med säkerhet terminologi inom området.
När eleven samråder med handledare bedömer hon eller han med säkerhet den egna förmågan
och situationens krav.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
13
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Plats för anteckningar:
14
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1 KOM IGÅNG MED PHP
Det här är en bok om webbserverprogrammering. Det finns programmering för olika
sammanhang:



Somliga program körs på en PC med Linux, Windows eller Mac OS X som operativsystem.
Somliga program körs i inbäddade system, d v s olika slags smådatorer som kanske
användarna aldrig ens tänker på att de är en dator
Somliga program körs på mobiltelefoner och kallas vanligtvis "appar".
Ordet körmiljö (Run Time Environment, RTE) används för att beteckna olika sammanhang där
ett program kan exekveras. För webben så finns det två grundläggande körmiljöer:


Klientprogrammering (client side programming, Front End Engineering) för kod som
ska köras (exekveras) inuti webbläsaren. Här dominerar JavaScript nästan fullständigt
som programmeringsspråk.
Webbserverprogrammering (server side scripting) för kod som ska köras på
webbservern. PHP är det vanligaste språket för den här sortens programmering, men
det finns många alternativ.
Smakprov från arbetsboken
Uppgift: Hitta fem vanliga alternativ till PHP. Tre till Apache. Fem till MySQL/MariaDB.
Vad är en körmiljö?
Körmiljöer är ett ord som betecknar den kombination av hårdvara och gränssnitt, i vilket
ett program exekveras. (Gränssnitt är ett programs ”kontaktyta” mot andra program och
system.) Faktorer som operativsystem, mjukvarubibliotek och nätverk påverkar körmiljöns
utformning.
Det finns också något som bara kallas serverprogrammering, och då inkluderas också servrar av
andra slag (beräkningsservrar, LAN-servrar, etc).
PHP exekveras på servern och resultatet skickas till klienten, vanligtvis en webbläsare.
JavaScript körs (vanligtvis) på klienten och resultatet visas för användaren
Eftersom PHP främst är ett språk för webbserverprogrammering, så behöver vi börja med att
installera en webbserver med PHP-stöd innan vi på allvar kan testa någon kod. Vi kommer för
den här boken behöva installera tre saker:
© THELIN LÄROMEDEL & LARS GUNTHER 2013
15
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1. Webbservern. Den vanligaste är Apache, men för 99 % av alla exempel i boken så funkar
det med vilken webbserver som helst, bara den stödjer PHP.
2. PHP.
3. En databashanterare. MySQL eller MariaDB används i boken (detta förklaras längre
fram).
4. För att skapa och sköta databaser så kommer vi använda PhpMyAdmin, som också
behöver installeras.
Lägg märke till att du för utvecklingsbehov först installerar dessa program på din egen dator.
Längre fram ska vi titta närmare på en mer komplett uppsättning servrar.
Ordet webbserver kan betyda två saker: Dels den dator (eller det kluster av datorer) som
är serverhårdvara, dels det program som tillhandahåller själva tjänsten att servera
resurser över http-protokollet. Den första sortens server är en dator man köper (eller hyr
in sig på), den andra är program man installerar på en dator.
När installationen är klar, så kommer du ha en webbserver installerad på din dator. Den mesta
PHP-kod som vi skriver kommer att köras genom den. Du kan inte öppna en PHP-fil direkt i
webbläsaren, utan webbservern måste anropas av webbläsaren, så att servern kan exekvera
PHP-koden och sända resultatet till webbläsaren. (Jag tjatar om detta, för av erfarenhet vet jag
att just denna ack så viktiga ”detalj” haft en säregen tendens att inte fastna i minnet på mina
elever.)
När installationen är klar, så behöver du hålla reda på vilken katalog i filsystemet som är
webbserverns arbetskatalog (webbroten, web root). Du måste lägga dina PHP-program i
den katalogen! Annars kan de inte köras. Du kan inte lägga PHP-filer i någon katalog
utanför denna, eftersom webbservern ska exekvera dem.
I kapitel xyz kommer vi gå igenom hur du kan göra dina egna inställningar som påverkar detta.
1.1
Installation av PHP på Linuxdatorer
Alla ledande Linuxdistributioner har färdiggjorda installationspaket för det vi behöver. Sök på
nätet efter hur det fungerar på just din distribution.
En sak att se upp med på Linux är att PHP-installationen ofta delas upp i många små delpaket.
Innan du går vidare med kapitel tre, så behöver du eventuellt göra vissa tilläggsinstallationer för
att få med alla delar som behövs.
16
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1.2
Installation av PHP på Windows och Mac OS X
Du kan antingen installera alla nödvändiga program separat, genom att följa instruktionerna
som finns på deras webbplatser, men det är inget jag rekommenderar för nybörjare, eftersom
det finns en faslig mängd kombinationer av program och moduler att hålla reda på. I stället kan
du använda XAMPP, som ger dig alla de saker du behöver.
XAMPP finns också för Linux, men det är varken lättare eller tekniskt bättre att använda
XAMPP än Linuxdistributionernas egna programvarupaket.
Innan du installerar XAMPP, så finns det några viktiga saker att hålla reda på.


Du behöver normalt inte installera FileZilla FTP Server, Mercury eller Tomcat (gäller
Windows).
Om du använder installationsprogrammet, så välj inte att installera programmen som
systemtjänster, utan som vanliga program som du kan starta och stoppa manuellt, med
XAMPP:s egen kontrollpanel. Som systemtjänst så kommer programmen alltid starta
ihop med operativsystemet och sedan ligga och ta upp lite minne även när de inte
behövs.
XAMPP hittas på adressen http://www.apachefriends.org/en/xampp.html
PHP installeras, men är inget program du behöver starta och stoppa själv. Webbservern
(Apache) anropar PHP åt dig. Du kan nu starta webbservern. MySQL kommer inte behövas än på
ett tag.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
17
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1.3
Ett första PHP-skript
Traditionen bjuder att det första skript man ska köra är ”Hello World”, men det är för tråkigt, så
skriv i stället koden nedan i en textredigerare2. Lägg märke till att av utrymmesskäl så är raden
med det andra echo-kommandot radbruten över två rader här i läroboken, vilket jag markerar
med pilen . Du ska alltså inte skriva det tecknet!
<?php
header("Content-type: text/html; charset=utf-8");
if (empty($_GET['name'])) {
echo '<h1>Hej du okände</h1>';
} else {
echo '<h1>Hej ', filter_input('INPUT_GET', 'name', 
FILTER_SANITIZE_SPECIAL_CHARS), '</h1>';
}
Spara detta i din webbrot som hello.php och (med webbservern igång) öppna sedan adressen
http://localhost/hello.php med din webbläsare. Resultatet ska se ut ungefär så här:
Ändra nu adressen något och skicka med en GET-parameter3:
http://localhost/hello.php?name=Åsa
Resultatet ska nu bli så här:
Testa gärna med ett namn som innehåller någon av våra krångliga bokstäver (å, ä eller ö).
Så vad är det som händer?
2
Se avsnittet om verktyg (2.4.1) i Läroboken Webbutveckling 1. Ett traditionellt exempel finns i PHP-manualen:
http://www.php.net/manual/en/tutorial.firstpage.php
3
Se avsnittet Query strings och fragment identifiers (1.4.5) i Läroboken Webbutveckling 1.
18
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK









På första raden har vi en tagg som säger till tolken att det som nu följer är PHP-kod och
ska tolkas som sådan. Varför den behövs framgår av nästa exempel. Filändelsen ska
också vara php, annars kommer webbservern (normalt) inte ens att försöka tolka PHPkoden.
Andra raden är en instruktion till webbservern att skicka ett HTTP-huvud, som klargör
att innehållet är av MIME-typen text/html och att teckenkodningen är UTF-8.4 Det
första är standardvärde (default), men det är inte helt säkert att teckenkodningen som
standard är UTF-8. Testa gärna att ta bort denna rad och se om resultatet blir
annorlunda.
På tredje raden så har vi ett villkor, där vi frågar om det finns en GET-parameter som
heter ”name” och om den i så fall har ett värde, vilket som helst utom 0 (noll). Eller
rättare sagt, vi frågar om den saknas eller om den finns och har värdet 0. I båda fallen
betraktas variabeln som tom (empty) och rad fyra utförs.
På rad fyra används kommandot echo, som alltså skriver något, i vårt fall en rubrik på
nivå ett med textinnehållet ”Hej du okände”. Här skrivs alltså ett fragment HTML ut, men
att för PHP är HTML-koden att betrakta som vilken text som helst. Att det förekom en
HTML-start- och sluttagg i det som skulle skrivas ut påverkade inte PHP-tolken det allra
minsta.
Rad fem är den alternativa förgreningen i koden, som körs om villkoret inte var uppfyllt,
det vill säga om vi angivit en GET-parameter, med rätt namn och ett annat värde än en
nolla.
På rad sex har vi också en echo-sats, som är en förkortad version av tre separata echokommandon. Först skrivs ”<h1>Hej ” ut. Lägg märke till mellanslaget efter bokstaven ”j”,
som skapar lite utrymme mellan ordet ”Hej” och själva namnet.
Nästa echo-kommando skriver ut det namn som användaren uppgivit i URL:en, efter att
det skyddats mot enklare manipulation med funktionen filter_input. Den förvandlar
ihop med flaggan FILTER_SANITIZE_SPECIAL_CHARS tecken som < och > till ofarliga
entiteter.5 Så skulle någon skriva en parameter som innehåller HTML-kod, som i sin tur
kan innehålla (i framtiden farlig) JavaScript, så har vi i vart fall gjort det betydligt svårare
för den personen att få sitt skript att köras.
Det tredje echo-kommandot avslutar sedan HTML-elementet. De tre echo-kommandona
som körts i rad på det här sättet skapar tillsammans en enda sammanhållen sträng av
text.
Det finns ingen avslutande PHP-tagg. Många exempel slutar alltid med den, trots att den
är onödig och dessutom kan ställa till med problem. Slutar ditt skript i PHP-läge, så bör
det inte innehålla någon avslutande PHP-tagg!
4
Se avsnitten HTTP-huvuden, metoder och statuskoder (1.4.9), Unicode (6.5) och Mer om MIME (6.10) i Läroboken
Webbutveckling 1.
5
Se avsnittet Entiteter (6.4) i Läroboken Webbutveckling 1.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
19
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Förtydligande om echo. Detta fragment med PHP-kod:
echo 'foo';
echo 'bar';
Fungerar alltså på samma sätt som detta:
echo 'foo', 'bar';
I båda fallen blir resultatet att foobar skrivs ut i det dokument som sedan skickas till
webbläsaren. Att det finns en nyrad eller ett mellanrum mellan kommandona i PHP-koden
påverkar inte resultatet. Varken mellanrum eller nyrad ingår i det som vi instruerat PHP att
skapa som ett resultat av koden.
Lägg också märke till att vi ännu inte skapat en komplett webbsida! Tittar du på HTMLkoden som skickats till webbläsaren, så ser den ut så här:
20
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1.4
En komplett webbsida med inslag av PHP
Låt oss nu utöka vårt exempel till att bli en hel sida. Skriv följande kod och spara den som
hello2.php. Också här finns det en radbrytning i läroboken, som inte behövs egentligen.
<?php
if (empty($_GET['name'])) {
$name = 'du okände';
} else {
$name = filter_input('INPUT_GET', 'name', 
FILTER_SANITIZE_SPECIAL_CHARS);
}
// Här börjar output
header("Content-type: text/html; charset=utf-8");
?>
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="utf-8" />
<title>Hello 2</title>
<style>
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<h1>Hello 2</h1>
<?php
echo "<p>Hej $name</p>\n";
?>
</body>
</html>
© THELIN LÄROMEDEL & LARS GUNTHER 2013
21
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Om du testar detta i din webbläsare, så ska resultatet se ut så här:
I det här exemplet blandar vi PHP-kod med vanlig “rå” HTML. Genom PHP:s start och
sluttaggar, så går tolken in och ut ur PHP-läge. Det är just här som det kan bli grötigt och
svårt att se både säkerhetsproblem och funktionsfel. Därför så börjar vi redan från början
med en grundläggande kodseparation.


Först har vi ett stycke PHP-kod, där det utförs tester, beräkningar och bearbetningar.
Sedan har vi HTML-kod som fungerar som en mall (template). Lägg märke till
växlingen mellan HTML-kod och PHP-kod före den avslutande body-taggen. I den kan
det finnas enkla villkor och loopar, men bara om det krävs för att skapa rätt ”output”
(resultat). Här sker inga beräkningar, inga säkerhetskontroller, ingen kommunikation
med databaser eller andra servrar, o s v.
I framtiden kommer mallar och annan slags kod inte bara ligga i två skilda delar inom samma fil,
utan vara helt skilda filer.
I koden ovan så introduceras en variabel, $name. Variabler i PHP börjar alltid med en s.k. sigil, i
PHP:s fall ett dollartecken. I stället för echo uppe i kontrollen, så sker nu en villkorlig tilldelning
(assignment) av ett värde till variabeln. Variabler lever vidare mellan de olika blocken av PHPkod, så när det nedre blocket stöter på samma variabelnamn, så fungerar det utan problem.
Till ett kommande kapitel:
Variabler behöver varken
deklareras eller instansieras innan de används i PHP.
Det är ingen skillnad i det slutliga resultatet mellan HTML-kod som skapats av echo eller andra
kommandon inuti PHP-blocken och den kod som återfinns mellan dessa block. Följande två
exempel är alltså funktionsmässigt identiska, om än det första är grötigt skrivet.
22
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
<?php
// Exempel ett
if ( $foo ) {
?>
Foo är sant
<?php
}
// Exempel två
if ( $foo ) {
echo 'Foo är sant ';
}
I det första exemplet, så lämnas PHP-läget, men det som skrivs är ändå villkorat av PHP-koden
som kommer först. Det kommer bara ingå i det slutliga resultatet om villkoret uppfylls, d v s om
variabeln $foo tolkas som sann.
Vill du snabbtesta några rader PHP-kod, utan att omge dem med HTML-kod, så kan du
ange följande HTTP-huvud: header("Content-type: text/plain; charset=utf-8");
1.5
Variabler, enkel- och dubbelfnuttar
I exemplet ovan hade vi denna rad PHP-kod:
echo "<p>Hej $name</p>\n";
Här skrivs alltså variabeln inuti en textsträng som omges av dubbelfnuttar (citationstecken). I
det fallet kommer PHP alltså att ersätta variabeln med dess innehåll. Skulle vi däremot använt
enkelfnuttar, så hade PHP skrivit ut den exakta frasen ”<p>Hej $name</p>”.
Textsträngar som omges av dubbelfnuttar tolkas logiskt, medan textsträngar som omges
av enkelfnuttar tolkas slaviskt.
I vårt enkla exempel så föreligger ingen risk för att variabelnamnet feltolkas, men låt säga att vi
har en situation där variabeln följs direkt av en bokstav:
© THELIN LÄROMEDEL & LARS GUNTHER 2013
23
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
// $typ förväntas antingen vara ordet ”start” eller ”slut”
echo "$typmånaden är…";
Här kommer alltså PHP att tolka det som att variabelnamnet är $typmånaden. Detta kan vi
åtgärda genom att använda måsvingar:
echo "{$typ}månaden är…";
Exemplet är kanske något konstruerat, men den här sortens situationer dyker upp ibland. När vi
kommer fram till kapitlet om arrayer så blir det rent utav vanligt. För att slippa strul, så
rekommenderar jag därför att du alltid använder måsvingar när variabler finns i textsträngar
som omges av dubbelfnuttar.
Koda på det sätt som när det används konsekvent ger dig så lite onödiga bekymmer som
möjligt. Var inte lat och spara in på antalet tangentnedtryckningar på tangentbordet. Det
kommer kosta dig betydligt mer onödiga fel och förlorad arbetstid, än vad du vinner i
bekvämlighet i början.
Bakstreck (backslash) har en speciell funktion när den förekommer mellan citationstecken. Den
anger då ett specialtecken. PHP ”lämnar” (escape) sitt normala sätt att tolka tecknen. För
enkelfnuttar gäller följande escape-koder (escape sequences):
'Tim O\'Reilly'
'\\'
 Efterföljande enkelfnutt ingår i strängen
 En backslash, bokstavligen
Omgiven av dubbelfnuttar, så finns det fler escape-koder, som i dessa exempel:
"<p lang=\"en\">"  En backslash, bokstavligen
"</p>\n"
 Nyradstecken (snyggare HTML-kod)
"\$foo"
 $foo är inte en variabel, bokstavligt dollartecken
24
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1.6
Några korta anmärkningar om PHP som språk (syntax och
kompilering)
PHP är ett programmeringsspråk som tillhör C-familjen, där finns också Java, (delvis) JavaScript
och en mängd andra språk, utöver just C och C++. Har du programmerat i något av dessa så
kommer du känna igen många saker:




Språket är uppbyggt genom satser (statements), vilka avskiljs med semikolon. Glöm inte
semikolonen! (Om jag fått en krona varje gång en elev glömt ett semikolon, så vore jag
en rik man idag.)
Ett antal satser kan grupperas till ett block och dessa avskiljs genom måsvingar, ungefär
som deklarationsblocken i CSS. Indrag av alla satser i ett block är frivilligt rent tekniskt,
men obligatoriskt ur varje annan synvinkel. Återigen, var inte lat. Utan indrag blir det
ytterst svårt att läsa din kod. Obalanserade måsvingar är det näst vanligaste
nybörjarfelet, efter glömda semikolon.
Alla språken i C-familjen har samma grundläggande styrstrukturer (if-else, while, dowhile, etc.)
Kommentarer kan börja med två ”framåtslashar”(//) och gäller då resten av raden, eller
så kan de omges av /* och */, som i CSS. (PHP kan också börja sina kommentarer med
tecknet #. Det är ovanligt, utom när PHP används som konsollskript.) En speciell slags
kommentarer är anpassade för PHPDoc – ett automatiskt system att skapa
dokumentation om din PHP-kod. De börjar med /** (två stjärnor) och slutar med */.
Exempel kommer i nästa kapitel.
Som lärare har jag ibland vägrat hjälpa elever innan de fixat sina indrag, eftersom det tar
på tok för låg tid för mig som hjälpare att sätta mig in i programmets struktur utan dessa.
Det har då många gånger hänt att eleven själv hittat felet under tiden hon eller han fixat
till sina indrag…
Till skillnad från de andra nämnda språken, så måste variabler i PHP som sagt börja med ett
dollartecken. Till skillnad från Java, C och C++, och i likhet med JavaScript, så behöver variabler
inte deklareras i PHP.
PHP behöver inte kompileras, utan det är ett tolkat (interpreterat) språk. C och C++ kompileras
normalt till maskinkod (exekverbara filer) och Javakod kompileras manuellt till bytekod, men för
PHP sker motsvarande optimering automatiskt. Den dag du jobbar på webbplatser som får
hundratals träffar i minuten, så kan du behöva lära dig hur man kan undvika ständig omtolkning
av koden, men till dess behöver du bara veta att manuell kompilering är onödigt, med PHP.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
25
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
1.7
OK, hur lär jag mig detta?
Utöver att läsa den här boken, se dess videos och göra dess övningar? Glad att u frågade,
eftersom boken absolut inte kommer att kunna täcka allt. Då skulle den bli väldigt tråkig att läsa.
Och återigen, det finns ingen anledning att skriva om PHP:s manual. Den finns redan och är
ypperlig!
1.7.1 Experimentera mycket
Variera alla exempel du får i den här kursen. Lägg till, dra ifrån, ändra, testa och fråga!
1.7.2 Bekanta dig med PHP-manualen
Den är din bästa vän som utvecklare. Också erfarna PHP-programmerare har manualen framme
när de jobbar. Det finns enorma mängder funktioner i PHP. Ingen kan alla.
http://www.php.net/manual/en/index.php
Till det här kapitlet passar avsnitten Getting Started (http://www.php.net/manual/en/gettingstarted.php) och Basic Syntax (http://www.php.net/manual/en/language.basic-syntax.php).
1.7.3 Använd den världsvida PHP-gemenskapen
Det finns gott om människor som vill hjälpa dig komma igång med PHP och ge dig konstruktiva
tips om hur du kan lösa dina problem, men kom också ihåg att det finns många som vill, men
ännu inte borde, hjälpa andra. Sök efter hjälp på flera ställen. Fråga specifikt efter säkra
lösningar som bygger på best practice.
Lägg till nyckelord som ”secure” och ”best practice” när du söker på webben!
1.7.4 Låt PHP rapportera varenda småfel du gör
PHP är ett oerhört förlåtande språk. Om du missat en liten detalj, så kommer PHP ofta göra en
kvalificerad gissning och så att säga hjälpa dig på traven. Detta är en god sak, då det gör så att
dina PHP-skript räddar dig undan totalt haveri och åtminstone ger användaren ett någorlunda
användbart resultat – ibland! Det kan också leda till totalt oväntade resultat eller slappa
kodvanor!
På din utvecklingsdator ska du därför se till att PHP rapporterar minsta lilla småfel som
upptäcks. Detta kan illustreras med ett skript. Oroa dig inte för de tekniska detaljerna
26
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
<?php
$a = array("foo" => "bar");
error_reporting(E_ERROR);
echo $a["foo"];
echo $a[foo]; // Obs inga fnuttar runt foo på denna rad
echo "<hr />";
error_reporting(E_ALL);
echo $a["foo"];
echo $a[foo]; // Obs inga fnuttar runt foo på denna rad
När skriptet körs, så kommer resultatet bli som på den här bilden:
Vi använder arrayer, något som förklaras längre fram i boken, men det du ska lägga märke till är
att först körs två echo-satser med en ganska förlåtande felrapportering. I det andra fallet så har
vi en strikt felrapportering, som inkluderar notiser. En felnotis är något som kan ha gått snett,
men kanske inte. I det här fallet så dök bokstäverna foo upp. PHP tolkar dem som en konstant,
men någon motsvarande konstant har inte definierats, varför PHP ”låtsas” som om det fanns en
sådan, med samma innehåll som den heter.
I det här fallet är ingen större skada skedd och på en produktionsserver bör därför
felmeddelandet döljas, men som utvecklare vill du veta alla dessa små detaljer.
Efter att du installerat PHP på din dator, så leta öppna filen som heter php.ini. I den hittar du
raden (som inte börjar med semikolon = kommentarer) med direktivet error_reporting. I PHP
5.3 och lägre så ska den ha värdet:
error_reporting = E_ALL | E_STRICT
Lägg märke till att vertikalstrecket(|) ska vara mellan de två värdena. I PHP 5.4 och högre ska
den raden ha värdet:
error_reporting = E_ALL
© THELIN LÄROMEDEL & LARS GUNTHER 2013
27
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Från och med version 5.4 så ingår nämligen E_STRICT i E_ALL.
Fattar du noll? Strunt i det och följ instruktionen ändå. Vi återkommer till felhantering
längre fram i boken.
En annan skillnad mellan utvecklingsmaskiner och produktionsservrar är att på de senare bör
felen loggas, medan de på utvecklingsmaskiner bör visas. I filen php.ini, så bör det finnas en rad
med följande värde:
display_errors = On
Om du gjort några ändringar nu, så starta om webbservern innan du fortsätter.
Saker som kommer finnas i övningsboken
Uppgift: Installera – duh! Inklusive felrapporteringen i 1.7.4
Göra och variera de två skripten
Testa enkel- och dubbelfnutt med variabler
Glöm semikolon och måsvingar med flit. Skriv ner vilket felmeddelande som det blev.
Skriv kommentarer med // och /* */
Svara på några frågor som med hjäp av PHP-manualen online
28
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
2 NÅGRA YTTERLIGARE EXEMPEL
I stället för att börja med en detaljerad teknisk diskussion, så kommer här några exempel.
Tanken är att du ska få en överblick om hur PHP fungerar. Det är därför viktigt att du prövar och
experimenterar med exemplen! Det är viktigare än att du förstår detaljerna.
För att spara plats, så visas inte ett helt HTML-dokument i exemplen, utan bara de delar som
gäller PHP-koden. Strukturen ser ut som följer. Lägg märke till vad som står inom hakparentes,
för detta är vad som kommer att variera mellan exemplen. Spara denna gärna som en mall. (Du
ska inte ha med hakparenteserna när du skriver in egna ord och angiven kod.)
<?php
/**
* [Med en mening förklaras vad denna fil innehåller och gör]
*
* [Med några meningar förklaras det i mer detalj.]
*/
[Kodblock med inställningar och inledande bearbetningar]
header("Content-type: text/html; charset=utf-8");
?>
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="utf-8" />
<title>[Varierande sidtitel som du hittar på själv]</title>
<style>
body {
font-family: sans-serif;
/* + tillägg du vill göra för att göra sidan lite snyggare */
}
</style>
</head>
<body>
<h1>[Varierande rubrik som du hittar på själv]</h1>
<?php
[Kodblock med output]
?>
</body>
</html>
© THELIN LÄROMEDEL & LARS GUNTHER 2013
29
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
2.1
Visa datum, månad, tid, etc
PHP kan visa tid på olika sätt, men att få PHP att göra det på svenska begränsar urvalet.
Antingen får man som utvecklare bygga sitt eget system, eller så får man använda funktionen
strftime(). Det är den enda som tar hänsyn till locale, d v s inställningar för format och språk
gällande klockslag och datum, sifferformat (decimalpunkt eller decimalkomma), valuta och
texthantering.
Det övre blocket med PHP-kod:
date_default_timezone_set("Europe/Stockholm");
setlocale(LC_ALL, "sv_SE", "Swedish");
Det nedre blocket med PHP-kod:
echo "<p>" . strftime("%c") . "</p>\n";
Spara, förslagsvis med namnet kap2-tid.php i din servers webbrot och testkör i webbläsaren.
2.1.1 Kommentarer till koden
Med textsträngen %c (litet c), så anges att tid ska skrivas ut med både datum och klockslag enligt
operativsystemets standardformat, vilket varierar mellan olika system. Funktionen strftime()
tar en mängd olika alternativ. Här kommer några alternativ att testa. (Gör det!)
echo "<p>" . strftime("%Y-%m-%d") . "</p>\n";
echo "<p>" . strftime("%A, %d %B %Y") . "</p>\n";
echo "<p>" . strftime("Klockan %H:%M:%S") . "</p>\n";
// Kortform av förra exemplet, strular på Windows
echo "<p>" . strftime("Klockan %T") . "</p>\n";
echo "<p>" . strftime("Klockan %R") . "</p>\n";
// Nedanstående strular också på Windows
echo "<p>" . strftime("Veckonummer: %V") . "</p>\n";
Hur lär man sig alla dessa kryptiska koder? Svar: Det gör man inte. Man läser manualen! De
finns beskrivna på sidan http://se1.php.net/manual/en/function.strftime.php och där kan du
hitta ännu fler varianter att testa. OBS! Några av dem funkar inte alls på Windows!
Testa också att byta locale eller att byta tidszon. Här kommer ett exempel:
date_default_timezone_set("America/Los_Angeles");
setlocale(LC_ALL, "en_US", "English");
30
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Om du sitter på en Windowsmaskin och vill jämföra med hur det blir på Linux, så gå till
exempelvis http://sandbox.onlinephpfunctions.com/ och testa din kod där.
2.1.2 Fördjupning om locale och tidszon
(Du kan hoppa över den här förklaringen tills vidare och återkomma till den när du lärt dig lite
mer om PHP och funktioner i kapitel 9.)
Funktionen för att ställa in locale behöver minst två argument, först en konstant som talar om
vilka inställningar som ska styras, LC_ALL, i vårt exempel ovan betyder ”alla”. Sedan följer en
eller flera strängar, som PHP-funktionen prövar i tur och ordning, tills den hittat en som
fungerar. Vanligtvis behövs det en för PHP som körs på Linux och andra Unix-liknande
operativsystem, inklusive Mac OS X, och en för Windows. Funktionen returnerar det alternativ
som använts. Själv använder jag ofta följande kodsnutt, som jag inkluderar (se kapitel 4) för alla
skript:
$CURLOCALE = setlocale(LC_ALL, 'sv_SE', 'sv_SE.UTF8', 'swedish', 'sve');
if ( ! strlen($CURLOCALE) ) {
user_error('Locale inte inställd!', E_USER_WARNING);
}
På ett motsvarande sätt kan jag kontrollera att inställningen av tidszon lyckades:
$TZ_SET = date_default_timezone_set('Europe/Stockholm');
if ( !$TZ_SET ) {
user_error('Tidszon inte inställd!', E_USER_WARNING);
}
2.2
Ett slumpmässigt valt citat
Övre kodblocket:
// Citat av Rasmus Lerdorf, som uppfann PHP från början
// http://en.wikiquote.org/wiki/Rasmus_Lerdorf
$alla_citat = array(
"I did not develop the PHP we know today. Dozens, if not hundreds of
people, developed PHP. I was simply the first developer.",
"I actually hate programming, but I love solving problems.",
"I've never thought of PHP as more than a simple tool to solve
problems.",
© THELIN LÄROMEDEL & LARS GUNTHER 2013
31
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
"For all the folks getting excited about my quotes. Here is another
- Yes, I am a terrible coder, but I am probably still better than
you :)"
);
$random_key = array_rand($alla_citat);
$citat
= $alla_citat[$random_key];
Nedre kodblocket:
echo "<p lang=\"en\">{$citat}</p>\n";
Spara, förslagsvis som kap2-citat.php och provkör i webbläsaren. Ladda om sidan flera gånger
när du testar koden!
2.2.1 Kommentarer till koden
Först definierar vi en array, som jag brukar jämföra med en byrå med lådor. En enkel variabel
kan innehålla ett tal, en textsträng eller ett booleskt värde (sant/falskt) och har ett namn. Om
en sådan variabel är som en enkel låda, med en etikett på, så är etiketten variabelnamnet och
lådans innehåll dess värde. En array är alltså som en byrå som innehåller flera sådana lådor. I
vårt fall så är det en lista med textsträngar (citaten), som skrivs inom fnuttar och skiljs åt med
kommatecken. Varje ”låda” kommer få ett nummer från noll och uppåt, det är dess nyckel (key).
Vi väljer ut en slumpmässig arraynyckel och lagrar den i en variabel.
Vi kopierar värdet som motsvarar denna nyckel till en enkel variabel.
Och i det nedre kodblocket, så skriver vi ut citatet.
2.3
Räkna antalet tecken i ett namn och skriv det baklänges
Låt oss ta ett lite större exempel. Kom ihåg att det ännu inte är meningen att du ska begripa
varje detalj, utan att det handlar om att få en övergripande idé om hur PHP fungerar. I det här
exemplet ska vi be användaren skicka sitt namn via ett formulär, och sedan räkna antalet tecken
i namnet, och skriva ut det framlänges, dess teckentantal och baklänges.
För att kunna göra detta, så behöver vi trixa lite med några funktioner, så att teckenkodningen
blir rätt. Att vända på en text vore enkelt om vi kunde veta att texten som skickats bara innehöll
tecken från det engelska alfabetet, eftersom det finns en funktion som kan vända på sådana
strängar. (Den heter strrev() – läs det som ”string reverse” – men den kan vi alltså inte
använda.)
32
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
PHP skapades innan UTF-8 hade slagit igenom som teckenkodning på webben och därför
är de vanliga funktionerna för textsträngar i PHP anpassade för Win-1252/ISO-8859-1.
Vi börjar emellertid med formuläret. Nedre HTML-koden ser nu ut så här:
<body>
<h1>Avsnitt 2.3: Namntest</h1>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<p>
<label for="name">Vad heter du?</label>
<input type="text" name="name" id="name"
placeholder="ex. Åke Svensson" />
</p>
<p>
<input type="submit" value="Testa namnet" />
</p>
</form>
<?php
// Kod kommer senare
?>
</body>
Spara, exempelvis som kap2-namn-test.php och testa i webbläsaren. Tittar du på HTML-koden
som skapats (CTRL+U), så ska den se ut så ut så här för formulärets starttagg:
<form action="/kap2-namn-test.php" method="post">
Namnet på skriptet som körs finns alltså i $_SERVER['PHP_SELF']. Men ännu händer inget när
formuläret skickas. Låt oss därför gå till det övre kodblocket.
I koden nedan finns det flera mycket krångliga koder. Stirra inte på dem. Det väsentliga är
följande:



Variabeln $submitted_name innehåller det som användaren skickat I formuläret, med
en viss grundsäkring mot hemska tecken som NULL och liknande. Vi tar också bort
onödiga whitespace-tecken i början och slutet, som – om de finns – troligen skrivits dit
av misstag.
Variabeln $output_name är samma data, fast säkrat för att skrivas på en webbsida, så att
ingen kodinjektion kan ske.
Variabeln $charcount är antalet tecken i namet. Vi kan räkna dem med en inbyggd
funktion i PHP, mb_strlen(), som använder UTF-8, eftersom vi allra först ställer in det
som standard för alla funktioner som heter något på mb_.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
33
WEBBSERVERPROGRAMMERING 1 - LÄROBOK


Variabeln $name_reversed skapas med hjälp av den funktion som definieras i början.
Den säkras för output på samma sätt som $output_name.
$namedata håller reda på om något resultat ska visas eller inte.
Det är med hjälp av dessa variabler som vi kan kommunicera med mallen (som vi ännu inte
skapat). Det viktiga är nu att du förstår hur data flyter igenom applikationen, inte hur varje
enskilt kommado funkar.
Eftersom det nu förekommer så många krångliga benämningar, så föreslår jag att du skriver en
rad i taget och kontrollkör den, genom att skicka data i formuläret. Även om det inte finns någon
output än ifrån PHP-koden, så ska det inte heller finnas några felmeddelanden. Kom ihåg att
alltid balansera dina måsvingar.
// Sätt standardvärde (default) för alla mb-funktioner
mb_internal_encoding("UTF-8");
/**
* En utf8-funktion som vänder på en textsträng
*
* Denna funktion liknar PHP:s inbyggda strrev(), men förutsätter
* att teckenkodningen är UTF-8 och inte Win-1252/ISO-8859-1
* @param string $str En UTF-8 kodad sträng
* @return string Strängen i omvänd ordning
*/
function utf8_strrev($str) {
// Namnet baklänges – se detta som svart magi tills vidare!
preg_match_all('/./us', $str, $temp_arr);
return join('', array_reverse($temp_arr[0]));
}
// Hämta data från formuläret
$submitted_name = filter_input(INPUT_POST, 'name', FILTER_UNSAFE_RAW,
FILTER_FLAG_STRIP_LOW);
// En variabel som håller reda på om vi fått något användbart
// Vi börjar med att förutsätta att så inte är fallet
$namedata = false;
if (!empty($submitted_name) ) {
// Ta bort onödig whitespace i början och slutet
$submitted_name = trim($submitted_name);
// Säkra namnet för HTML_output
$output_name = htmlspecialchars($submitted_name, ENT_QUOTES);
// Antal tecken i namnet
$charcount = mb_strlen($submitted_name);
34
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
// Namnet baklänges - betrakta detta som svart magi tills vidare!
$name_reversed = utf8_strrev($submitted_name);
// Säkra för HTML-output
$name_reversed = htmlspecialchars($name_reversed, ENT_QUOTES);
$namedata = true;
}
Med dessa variabler nu definierade, så kan vi skapa vår mall. Efter formuläret och före den
avslutande </body>-taggen, så skriver vi in följande kod:
<?php
if ( $namedata ) {
echo <<<DATA
<dl>
<dt>Namn</dt>
<dd>{$output_name}</dd>
<dt>Antal tecken (inklusive ev. mellanslag i mitten)</dt>
<dd>{$charcount}</dd>
<dt>Namnet baklänges</dt>
<dd>{$name_reversed}</dd>
</dl>
DATA;
}
?>
Här sker en villkorlig utskrift, som definieras med s.k. heredoc-syntax. När man har långa
textsträngar, så är denna att föredra framför fnuttar. Heredoc-blocken börjar med <<< plus ett
namn och avslutas med namnet.
Det avslutande namnet i heredoc måste stå allra först på en egen rad och får inte följas av
något annat än ett semikolon. Inga indrag, inga efterföljande kommentarer, inte ens ett
mellanslag få finnas på samma rad!
Nu är vi klara. Spara och testkör. Skicka fantasifulla förslag i formuläret och försök injicera olika
slags HTML-kod, framlänges och baklänges!
© THELIN LÄROMEDEL & LARS GUNTHER 2013
35
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
3 PHP:S HISTORIA, VERSIONER, STYRKOR OCH
SVAGHETER
3.1
PHP:s historia
Rasmus L
Zend
3.2
Vem använder PHP
PHP är inte längre den coola nykomlingen som alla pratar om. PHP är numera etablerat, ja rent
av ett ganska tråkigt ”medelålders” programmeringsspråk. Det var längesedan någon upptäckte
PHP och fick en känsla av ”wow”. Det innebär att det inte längre skrivs och bloggas på samma
sätt som i början av 2000-talet om språket. Men det innebär inte att det är på tillbakagång.
Tvärtom så används PHP av ca 75 % av alla webbapplikationer och den siffran har ökat med ca
10 % under 2010-talet. Till användarna av PHP hör:





3.3
Facebook – världens enskilt största webbapplikation är i grunden skriven med PHP, även
om många tilläggstekniker också behövs.
Wordpress – världens vanligaste bloggplattform är skriven i PHP.
MediaWiki som används av Wikipedia och flera andra wikis är skriven i PHP.
Några av världens allra mest populära CMS:er är skrivna i PHP. Dit hör Drupal och
Joomla.
Några av världens mest populära system för diskussionsforum, som phpBB och Phorum.
Versionshistorik
Varför det finns ett behov av att hålla reda på versioner. Exempel:





PDO, inte stabilt före 5.2
Exempel med mysql-syntaxen? Tecken på att det är en gammal resurs!
const som komplement till define() i PHP 5.3
nowdoc i PHP 5.3
filter-funktionerna i PHP 5.2 – extra OBS för dessa. Sluta använd de superglobala
arrayerna
Inget ifrån PHP 5.4 eller senare kommer beröras i den här boken, vars effektiva miniminivå är
5.3
36
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Du kan inte räkna med att alla webbhotell har senaste versionen av PHP installerad. I början på
sommaren 2013, så fördelar sig olika versioner av PHP så här:6
En av fördelarna med att hålla sin installation är att nyare versioner av PHP har bättre
prestanda. Tiden som det tar att köra några benchmarks illustreras av detta diagram:7
6
Denna bild är lånad med tillstånd från Lorna Jane Mitchell, http://www.lornajane.net/posts/2013/php-versionadoption
7
Också denna bild är lånad med tillstånd från Lorna Jane Mitchell, http://www.lornajane.net/posts/2013/phpversion-adoption. Gå till hennes sida för mer utförliga förklaringar.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
37
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Skulle vi lägga in PHP 5.0 och 5.1 också, så skulle trenden bli ännu tydligare. Men framför allt så
är det bara de senaste versionerna av PHP som underhålls med säkerhetsuppdateringar. Att
köra en föråldrad version är alltså direkt riskabelt!
För PHP så gäller att utvecklingsversionen får alla nya funktioner och den stabila versionen får
enklare nya funktioner, medan versionen innan underhålls enbart för säkerhet och stabilitet. Av
säkerhetsskäl är det också viktigt att uppgradering sker till den senaste underversionen med
jämna mellanrum.
3.4
Hur bra är PHP?
PHP:s dåliga rykte




Växer med behoven, inte efter en plan = somligt kunde gjorts annorlunda, mer stilrent
och elegant. PHP är ett ”fult” språk, men det har vad du behöver.
Säkerheten – men är det språkets fel?
Den vildvuxna communityn – jämför med Ruby som har ett enda dominerande
framework (rails).
Inte längre den ”Hippa Nykomlingen”
UTF-8 är inte ”native” – bläh!
PHP:s styrkor



Manualen
Communityn
Tillgängligheten – alla webbhotell stödjer PHP
Inte rätt för alla, inte rätt för allt.
38
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
4 ATT ANVÄNDA PHP SOM ETT MALLSYSTEM
4.1
Samma sida, men olika innehåll
En mer genomarbetad praktisk övning
En sida med tre alternativa innehåll, beroende på en GET-parameter. (Emulering av
databasdrivet innehåll.)
4.2
Återanvändning av kod mellan olika sidor
Att inkludera delar av sidan som används på mer än en sida
include()
include_once()
require()
require_once()
© THELIN LÄROMEDEL & LARS GUNTHER 2013
39
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
5 PHP SOM PROGRAMMERINGSSPRÅK
Mål: Att kunna använda manualen, inte att skriva av den
OBS! Den som lärt sig delar av manualen har ”fått en (eller några) fisk(-ar)”, men den som lärt
sig använda manualen ”har fått ett metspö”
Det här kapitlet är som att lära sig det periodiska systemet i kemin, inte så kul i sig, men kan du
det, så är det lättare att skapa något som puttrar och smäller!
5.1
Kommentarer sparar tid
Det tar lite tid att skriva kommentarer, det tar massor av tid att inte ha kommentarer skrivna
Att provisoriskt ”kommentera bort” ett kodblock
PhpDoc
5.2
Värdetyper
Dynamiska typsystem kontra statiska
PHP:s typer
PHP-manualens extratyper
5.3
Variablers namngivning och räckvidd (scope)
Tekniska krav på variabler (vad de kan heta) och användarkrav (vad de bör heta)
Använd bara tecken som finns på det engelska tangentbordet, så kan du be om hjälp också
utomlands!
Skilj på GLOBALA, långlivade och kortlivade variabler
5.4
Tilldelning
By value
By reference
5.5
Några operatorer
5.5.1 Matematiska operatorer
Enkla
40
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Pre- och post-inkrement
5.5.2 Strängoperatorer
OBS! Konkatenering med punkt
5.6
Jämförelser, sant och falskt
Enkla jämförelser av skalära värden
== kontra ===
”Truthy” and ”falsy”
Fördjupning: Skillnader i typkonvertering mellan PHP och JavaScript (Summa: == inte lika farligt
som JS, där man alltid bör ha == utom vid jämförelse med null)
5.7
PHPCodeSniffer
© THELIN LÄROMEDEL & LARS GUNTHER 2013
41
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
6 SÄKERHETSTÄNK
6.1
Problemkällor
Klantiga användare – hjälp dem!
Black hat hackers – försvåra för dem!
Botar – skilj ut dem utan att försämra mer än nödvändigt för människor.
6.2



Principer
Försvar på djupet, inte skalförsvar
”Security through obscurity” har (faktiskt) ett begränsat värde
Regelbunden backup
6.3
Filter input – escape output
6.4
Fulkod döljer säkerhetshål – och är svårare att underhålla
6.5
Lägg allt utom det användaren ska anropa utanför webbroten
42
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
7 STRÄNGAR
HTML, CSS, SVG – det är text!
7.1
UTF-8 kräver mb-funktionerna
Detta fattar sällan amerikanerna, så läs deras tips med vaksamt öga!
Några enkla exempel
Att läsa manualen om dessa funktioner
7.2
Verifikation av välformad UTF-8
”Strip low” – ta bort kontrolltecken, speciellt NULL-tecknet.
7.3
Ta bort HTML eller ”eskejpa” den
© THELIN LÄROMEDEL & LARS GUNTHER 2013
43
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
8 ARRAYER
8.1
”Min array är inte lik din array”
Min array är associativ och används hela tiden
Vad är en array i PHP
8.2
Definiera arrayer, lägg till, ändra och ta bort värden
Nyckelordet array() – inte en function!
Array shorthand, som i JavaScript i PHP 5.4. Tips! Men används inte i boken.
By reference mellan array-medlem och enkel variabel
8.3
Använda arrayvärden i textsträngar
Behovet av måsvingar
Om man glömmer fnuttarna?
8.4
Loopa genom arrayer med foreach
PHP:s kanske mest flitigt återkommande struktur
8.4.1 Foreachloopar med tilldelning ”by reference”
Ett tips – stryks om boken blir för lång…
8.5
Array-liknande strukturer
Databasresultat
Objekt med ”iterator” som interface – nämns men förklaras inte i detalj.
44
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
9 FUNKTIONER I PHP
Duplicera aldrig kod! Så fort något ska göras mer än en gång, så skriv en funktion.
9.1
En funktions funktion
Namn
Parametrar
Standardvärden för parametrar
Returvärde
Scope
9.2
Sök i manualen, din funktion finns nog redan där!
9.3
Hellre returnera än skriva
Och pilla inte på de globala variablerna. Skicka dem som parametrar i stället.
Om du måste, använd $GLOBALS hellre än kodordet global – varje gång!
9.4
Dokumentera dina funktioner
9.5
Håll alla definitioner för sig och inkludera dem
© THELIN LÄROMEDEL & LARS GUNTHER 2013
45
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
10
OBJEKT I PHP
Med PHP kan du programmera OO fullt ut, men vi ska bara titta på de enklaste grunderna
PHP:s arrayer är så kraftfulla att de ersätter objekt vid många tillfällen där andra språk skulle
använt dem
10.1 Vad är ett objekt
Har egenskaper och metoder
StdClass
10.2 Klasser – objekt av en viss typ
Definiera en klass
Metoder och $this
Objektens egenskaper och deras synlighet
Konstanter
Konstruktorer
10.3 Statiska metoder
Lite kort för att känna igen PAAMAYIM NEKDOTAYIM
Ev. statiska metoder och konstanter som en enkel namnrymd
10.4 OO syntax i PHP kontra andra språk
Punkttecknet är konkateneringsoperator i PHP
JS foo.bar blir $foo->bar i PHP.
46
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
11
DATABASER OCH DATALAGRING
11.1 Alternativ
Orientering om




Lagring i filer
Relationsdatabaser
No-SQL
Lagring på klienten
11.2 MySQL och MariaDB
Monty och Oracle…
11.3 Databaser och databashanterare (DBMS)
RDBMS
11.4 Tabeller, fält, index, poster, relationer
11.5 PhpMyAdmin
Skapa en databas
Skapa en tabell för läxhjälpens blogg
© THELIN LÄROMEDEL & LARS GUNTHER 2013
47
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Lägg in några poster
INSERT INTO `laxhjalpen`.`articles` (`articlesID`, `slug`, `title`, `text`,
`username`, `pubdate`) VALUES (NULL, 'test1', 'Första testartikeln', 'Lorem
ipsum dolor sit amet...', 'mia', NOW())
Se till att du har värden med åäö någonstans med för att inte bli tagen på sängen längre
fram när detta strular!
Skapa en tabell för läxhjälpens bloggkommentarer
48
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Lägg in några poster
Skapa en tabell för läxhjälpens användare
Lägg in några poster
11.6 PHP och databasen
PHP-applikationerna behöver kunna ansluta till databasen. I förhållande till databashanteraren,
så är PHP en klient, som behöver autentiseras och ges precis lagom mycket privilegier.
Skapa en separat användare åt dina PHP-skript med hjälp av PhpMyAdmin och ge den
användaren minsta användbara mängd privilegier.
OBS!
Bra för lärare att alternativet finns!
© THELIN LÄROMEDEL & LARS GUNTHER 2013
49
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
Bara detta:
50
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
12 ATT ANSLUTA TILL EN DATABAS OCH HÄMTA
VÄRDEN
12.1 Välj ett modernt gränssnitt!
Dags att ansluta ifrån vår egen PHP-kod. För att ansluta till en MySQL/MariaDB-server, så finns
det tre gränssnitt att välja mellan:



mysql-gränssnittet, som enbart är procedurellt och helt föråldrat. Detta behålls av PHPför att stödja gamla applikationer. Ska absolut inte användas för nyskriven kod!
Mysqli-gränssittet, där bokstaven i står för ”improved”. Ett bra alternativ som kom med
PHP 5.0 och kan användas både procedurellt och objektorienterat.
PDO-gränssnittet kom med PHP 5.1, men blev moget först med PHP 5.2. Det mest
väldesignade gränssnittet och dessutom inte bundet till en enskild RDBMS. PDO kan
alltså användas med Oracle, MS SQL, PostgreSQL, o s v, såväl som med MySQL/MariaDB.
Det finns några avancerade funktioner i MySQL/MariaDB som man inte kan komma åt via PDO,
utan bara med mysqli-gränssnittet, men vanligtvis så är PDO det bästa alternativet.
12.1.1 Databasabstraktion
När PDO kom år 2005, så var det mycket tal om ”databasabstraktion”. Med det avsågs att PHPapplikationer borde skrivas på ett sådant sätt att man ska kunna byta mellan olika RDBMS utan
att behöva röra på sin PHP-kod. Med abstraktion så menas att det finns ett slags ”mellanlager”
mellan den vanliga PHP-koden och databasen och detta mellanlager hanterar skillnaderna
mellan olika RDBMS. I praktiken är detta sällan ett stort problem för enklare PHP-applikationer,
men det kan efterfrågas bland utvecklare på enterprise-nivå, d v s de som skriver avancerade
applikationer för stora företag och organisationer.
Det finns tre nivåer av abstraktion:
1. Data-access-abstraktion. Detta får vi genom PDO och det innebär att gränssnittet i PHP
är oförändrat, oavsett RDBMS.
2. SQL-abstraktion. Detta innebär att skillnader i SQL-dialekt mellan olika RDBMS tas om
hand av abstraktionslagret. Detta ingår inte i PDO.
3. Datatypsabstraktion. Detta innebär att skillnaderna mellan hur olika RDBMS lagrar data
i själva databasen tas om hand av abstraktionslagret. Ingår inte i PDO.
För de enkla applikationer som vi ska bygga på nybörjarnivå, så är de två sista nivåerna total
overkill. Och för mer avancerade applikationer innebär de ofta att man tvingas avstå prestanda
och funktionalitet. Av dessa skäl är total databasabstraktion något tämligen sällsynt.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
51
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
12.2 Ett enkelt exempel
Vi ansluter till databasen med PDO genom att instansiera ett nytt PDO-objekt och göra
grundläggande inställningar för förbindelsen. Vi gör ett enkelt test. Det övre kodblocket:
<?php
header("Content-type: text/plain; charset=utf-8");
$dbh = new PDO('mysql:host=localhost;dbname=laxhjalpen', 'phpuser',
'[pw]');
if ( ! $dbh ) {
echo "Kontakt ej etablerad";
exit;
}
echo "Kontakt etablerad. Hurra!";
Du skriver självklart det lösenord du själv valt i stället för [pw]. Spara detta som anslut-test.php
och testkör tills det fungerar. Då har vi kommit en liten bit på vägen, men koden är långt ifrån
bra.
Vad är det för fel på den koden?
1. Användarnamn och lösenord är hårdkodade i PHP-koden direkt. Det är krångligt när
man ska göra anslutningar på flera ställen och direkt förkastligt ur säkerhetssynpunkt.
2. Vi hanterar inte möjligheten till att något går snett. Om kontakt inte kan etableras, så
kastar PDO ett s.k. undantag (exception) som måste hanteras. Annars avbryts
exekveringen tvärt. Detta är OK under tiden vi utvecklar, men så får det inte vara när
systemet tas i drift. Då ska användaren få ett snyggt felmeddeande och de ansvariga
meddelas omedelbart.
3. Koden gör (ännu) inre de grundläggande inställningarna som behövs för att vår
applikation ska fungera på bästa sätt.
Längre fram ska vi skapa en återanvändningsbar funktion som tar itu med alla de problemen,
men tills vidare vill vi främst testa grunderna, så vi fortsätter:
52
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
// Förbered en SQL-fråga att ställa till databasen
$sql = "SELECT * FROM articles ORDER BY pubdate DESC";
$stmt = $dbh->prepare($sql);
// Utför frågan
$stmt->execute();
// Loopa igenom resultatet och dumpa varje rad
while ( $article = $stmt->fetch()) {
var_dump($article);
}
While-loopen kommer snurra så länge som det finns artiklar att hämta. Varje rad i databasen
blir arrayen $article. Resultatet är inte snyggt, men det är heller inte avsikten. Vi fokuserar på
att få förbindelsen med databasen att fungera, och än så länge strular å, ä och ö. Vi kan fixa det
genom att ändra på raden som instansierade PDO-obejektet. Det som läggs till är kursivt.
$dbh = new PDO(
'mysql:host=localhost;dbname=laxhjalpen; charset=utf8',
'phpuser', '[pw]'
);
Med tillägget ; charset=utf8 direkt efter namnet på databasen, så kommer å, ä och ö att
fungera korrekt.
MySQL/MariaDB använder inga bindestreck när teckenkodning anges. Det annan kod
kallar UTF-8 eller utf-8, kallar MySQL/MariaDB för utf8.
12.3 En komplett funktion för att ansluta (en aning ”kokbok”)
För att undvika kodduplicering och minimera säkerhetsproblem, så skapar vi nu två filer:
settings.php och global.inc.php. Filerna ska inte ligga i webbroten, utan – som vi såg i kapitel 4
– så ska de ligga i en grannkatalog till den.
Den första innehåller användarnamn och lösenord, och den ska ärför inte ingå i det som
du versionshanterar och lägger upp på GitHub. Lägg till filnamnet i filen .gitignore. Innan
du checkar in dina ändringar första gången!
I settings.php ska dessa rader finnas:
<?php
define('MYAPP_DB_DBNAME', 'laxhjalpen');
define('MYAPP_DB_USERNAME', 'phpuser');
© THELIN LÄROMEDEL & LARS GUNTHER 2013
53
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
define('MYAPP_DB_PASSWORD', '[pw]');
define('MYAPP_TZ', 'Europe/Stockholm');
I global.inc.php skriver vi vår anslutningsfunktion. (Här blir det lite ”kokbok”, d v s kod att exakt
skriva av utan att det här finns plats att förklara alla detaljer.)
<?php
/**
* Funktion för att ansluta till en databas
*
* Funktionen förutsätter att några konstanter redan har satts:
* MYAPP_DB_DBNAME som är namnet på databasen att ansluta till.
* MYAPP_DB_USERNAME som är det användarnamn PHP använder.
* MYAPP_DB_PASSWORD som är lösenordet.
* MYAPP_TZ som är den tidszon som applikationen ska fungera inom.
* Funktionen kan anropas flera gånger, utan att någon ny uppkoppling
sker.
* Funktionen gör grundläggande inställningar kring UTF-8 och
* svensk tidszon för databasförbindelsen.
*
* OBS! Funktionen saknar ännu vettig felhantering!
*
* @return PDO Databaskopplingen som ett PDO-objekt
*/
function get_dbh()
{
// Uppkopplingen återanvänds
static $dbh;
if ( is_null($dbh) ) {
// Kontroll av "parametrar"
$dsn
= "mysql:host=localhost;dbname=" . MYAPP_DB_DBNAME;
// Lite grundläggande inställningar
$attributes = array(
// Fortsätt kasta exceptions för alla fel
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// En specialgrej för MySQL/MariaDB…
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
// Använd associative arrayer när svar hämtas som standard
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
54
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
try {
$dbh = new PDO($dsn, MYAPP_DB_USERNAME, MYAPP_DB_PASSWORD,
$attributes);
if ( empty($dbh) ) {
throw new Exception(
"PDO kunde inte instansieras, uppkoppling misslyckad.");
}
// Ställ in tidszon för förbindelsen
$ts_sql = "SET time_zone = '" . MYAPP_TZ . "'";
$svar
= $dbh->query($ts_sql);
// Lite inställningar för MySQL under utveckling
// Tolerera INGA fel under utveckling,
// bli generösare för drift.
// OBS! Inget mellanrum mellan kommatecknen på raden nedan!
$mode_sql = "SET SESSION sql_mode = 
'STRICT_ALL_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE'";
$svar
= $dbh->query($mode_sql);
}
catch(Exception $e) {
// Som sagt: Felhanteringen är inte klar.
echo "<pre>";
var_dump($e);
echo "<hr />";
var_dump($dbh);
echo "<hr />";
exit;
}
}
return $dbh;
}
Nu kan vi testa denna funktion, genom at skapa filen anslut-require-test.php som ska ligga i
webbroten. Dess innehåll är fortfarande ofullkomligt, men syftet är främst att testa funktionen
ovan.
© THELIN LÄROMEDEL & LARS GUNTHER 2013
55
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
<?php
header("Content-type: text/plain; charset=utf-8");
require("../includes/settings.php");
require("../includes/global.inc.php");
$dbh = get_dbh();
$sql = "SELECT * FROM articles ORDER BY pubdate DESC";
$stmt = $dbh->prepare($sql);
$stmt->execute();
while ( $article = $stmt->fetch()) {
var_dump($article);
}
Först ska du få detta att fungera utan felstavningar och missade måsvingar, etc. När du får ett
resultat, så lägg märke till att $stmt->fetch() beter sig lite annorlunda nu. Det förklaras strax.
12.4 Prepared statements
När vi har ett PDO-obekt, så finns det flera metoder som vi kan använda. Den enklaste är
$dbh->query($sql), om objektet heter $dbh och $sql är en SQL-fråga. Vi använde denna för
att utföra enklare inställningar för uppkopplingen, men i övrigt bör den ersättas av en
tvåstegslösning:
$stmt = $dbh->query($sql);
// Gör exakt samma sak som
$stmt = $dbh->prepare($sql);
$stmt->execute();
Så varför är den andra versionen bättre?
1. Den låter oss återanvända samma fråga flera gånger utan att tappa prestanda, vi kan
med andra ord förbereda frågan en gång, men utföra den flera gånger. Därav namnet
prepared statements och traditionen att kalla dessa objekt $stmt.
2. Men framförallt, så tillåter den oss att använda säkra platshållare (placeholders), där vi
kan stoppa in data som är osäker och kan ge upphov till SQL-injektioner. Enklast görs
detta med metoden $stmt->bindParam().
56
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
PDO är ett slags objekt, PDOStatement ett annan slags objekt. De hör ihop, men ska inte
förväxlas. Både $dbh->query() och $dbh->prepare() returnerar alltså ett PDOStatementobjekt. Ett normalt programflöde ser då ut så här:
PDO
prepare()
PDOStatement
bindParam()
execute()
fetch()
Svarsrad från en
eller flera tabeller
Sedan ett statement utförts, så kan vi alltså hämta hämta en rad i taget med metoden fetch().
Om vi inte gjort några ändringar i standardinställningarna, så returnerar fetch() en array som
är både associativ och sifferindexerad. Det är normalt sett onödigt och en aning besvärligt.
I vår funktion ovan, så ställde vi in PDO så att endast en associativ array returneras som
standard. Vill man göra ett lokalt undantag, så finns det flera olika alternativ att välja mellan. Jag
listar några:
$stmt->fetch(PDP::FETCH_ROW)
 Endast en sifferindexerad array returneras.
$stmt->fetch(PDP::FETCH_ASSOC)
 Endast en associativ array returneras.
$stmt->fetch(PDP::FETCH_BOTH)
 En kombinerad array returneras.
$stmt->fetch(PDP::FETCH_BOUND)
 Används ihop med fördefinierade variabler.
$stmt->fetch(PDP::FETCH_OBJ)  Ett objekt utan någon definierad klass returneras.
I den här boken håller jag mig till associativa arrayer.
12.5 Loopa igenom databasresultat
Ett mycket vanligt mönster för PHP-kod är att hämta flera rader ur en databas och sedan loopa
igenom dem. Foruminlägg, artiklar på en webbplats framsida, kommentarer som hör till ett
blogginlägg, Twitteruppdateringar – allt skapas genom loopar! På min facebooksida, så
identifierar jag minst 15 loopar, varav många har underloopar, men samtidigt vet jag att just
Facebook har många tidsbesparande speciallösningar. I vart fall är modellen hämta-loopa något
av det mest grundläggande som finns i webbserverprogrammering.
[Här kommer den färdiga boken ha ett exempel från läxhjälpen, där de senaste blogginläggen
visas på riktigt.]
© THELIN LÄROMEDEL & LARS GUNTHER 2013
57
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
12.6 Anteckningar
Ej klart avsnitt
http://php.net/manual/en/ref.pdo-mysql.connection.php
https://kb.askmonty.org/en/sql_mode/
Datan ifrån databasen är opålitlig!
58
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
13
INLOGGNING OCH LÖSENORDSHANTERING
13.1 Vad ska ett autentiseringssystem kunna?






Verifiera användare-lösenord kombinationen
Skapa nya användare
Verifiera epostadresser
Byta lösenord
Återställa lösenord för dem som glömt det – på ett säkert sätt!
Etc.
Om lösenorden läcker, så ska de ändå inte kunna knäckas (principen om försvar på djupet)
13.2 Bygga eget eller använda befintligt?
Persona
OpenID
Facebook, Google, etc.
13.3 Sessioner
Session hijacking
13.4 Inloggning för läxhjälpens administratörer
© THELIN LÄROMEDEL & LARS GUNTHER 2013
59
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
14
FORMULÄR OCH PHP
14.1 Ett första exempel
Som också stoppar botar utan captcha
Högprioriterade mål får sina specialskrivna botar och behöver andra system
14.2 Get och post
14.3 Läs med filter-funktionerna
Inte de superglobala arrayerna!
14.3.1 Historik över hur PHP hämtat formulärdata




Autoglobala variabler
$HTTP_POST_VARS (inte superglobal – borttagen)
Superglobala arrayer (använd dem som vore de ”read only”!)
Filter-extension
14.4 Sätt inte användaren på pottkanten
Ge vettiga felmeddelanden. Ur användarens synvinkel, inte systemets.
För en dialog med din interaktionsdesigner.
Skicka tillbaka också defekt formulärdata, så att användaren slipper upprepa sig.
Genom att ”posta till sig själv”
14.5 Hantera framgången rätt
Ge vettiga framgångsmeddelanden
Och tömma formuläret om det visas på nytt
Undvik möjligheten att dubbelposta
60
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
15
FRÅN FORMULÄR TILL DATABAS
15.1 Lägga in nya poster
15.1.1 Magic quotes helvetet
if ( get_magic_quotes_runtime() ) {
// Default exception handler gets to catch this one
throw new Exception('Magic quotes runtime are on. Application
requires them to be off.');
// Alla applikationer som använder databasen får själva hantera
magic_quotes_gpc
}
15.2 Ändra befintliga poster
15.3 Radera poster
© THELIN LÄROMEDEL & LARS GUNTHER 2013
61
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
16
SKICKA MEJL MED PHP
16.1 SMTP och SMTP-injektion
16.2 Ett exempel
Tipsa bloggaren om att en kommentar skrivits på läxhjälpen
(Egen uppgift slutuppgift: Tipsa den som kommenterat att svar skrivits, men bara om
mejladressen bekräftats)
16.2.1 Kontaktformulär för Läxhjälpen
62
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
17
ATT HA KUL MED PHP
17.1 Snygga URL:er
Med mod_rewrite
17.2 Skapa annat än HTML-kod
GD-biblioteket
17.3 Ajax
17.4 Webbtjänster – att kommunicera med andra servrar
17.5 Att skriva PHP-moduler för befintliga applikationer
Ex. Wordpress
17.6 Att använda ramverk och klassbibliotek
17.7 Internationalisering och lokalisering
+
Mer DB: Transaktioner, ACID, stored procedures, triggers… (inte gå igenom, bara tipsa om)
© THELIN LÄROMEDEL & LARS GUNTHER 2013
63
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
18
INFRASTRUKTUR FÖR UTVECKLING
18.1 En ”riktig” IDE
Debug
18.2 Utvecklingsmaskin, staging server, produktionsserver
Virtuella servrar
Skapa alias för localhost i din hosts-fil.
18.3 Webbhotell
18.4 Projekthantering och dokumentation
Github
PhpDoc
64
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
19 CHECKLISTA FÖR SÄKERHET OCH
KODKVALITET
För varje punkt ska du tänka så här: ”Kan jag svara på hur detta gjorts och har jag noga
kontrollerat att detta görs konsekvent och utan undantag?”
19.1 Preliminär kontroll
1. Är koden lättläst, välstrukturerad och skriven enligt en konsekvent kodstandard?
2. Är koden väl kommenterad?
3. Har alla funktioner, klasser, konstanter och variabler namngivits på ett konskekvent och
begripligt sätt?
4. Finns det någon rest kvar av duplicerad kod som inte flyttats till en funktion?
5. Etc
19.2 Kodkvalitet, egen kontroll
När jag tänker på den kod du skrivit, så…
1.
2.
3.
4.
5.
Vet jag hur SQL-injektioner stoppas?
Vet jag hur XSS stoppas?
Vet jag hur SMTP-injektioner stoppas?
Vet jag hur kodinjektion stoppas?
Vet jag hur lösenorden krypterats med bcrypt eller likvärdig teknik? (Vilka skäl har jag att
känna mig trygg om lösenordsdatabasen skulle komma till allmän kännedom?)
6. Vet jag att alla filer har konsekventa och begripliga namn och att de organiserats på ett
säkert och funktionellt sätt?
7. Vet jag att alla fält i databasens tabeller som kan bli underlag för urval eller sortering har
index?
8. Vet jag att cookies som inte ska användas av JavaScript är server side only?
19.3 Automatisk kontroll
1. Har jag kört PhpCodeSniffer?
2. Har jag kört PhpDocumentor?
3. Har jag checkat in min kod i versionshanteringssystemet? (Hela tiden under processens
gång.)
© THELIN LÄROMEDEL & LARS GUNTHER 2013
65
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
19.4 Extern kontroll
1. Har ett antal test-användare använt systemet både med god vilja och så att de försökt
klanta sig med flit?
2. Har någon kunnig på person inom säkerhet testat att utföra olika injektioner eller andra
slags attacker?
3. Har någon annan gått igenom min kod och påtalat eventuella brister?
19.5 Kontroll av webbhotell
1. Mitt webbhotell kör nya versioner av PHP och andra programvaror och uppdaterar dem
snabbt när nya säkerhetspatchar kommer ut?
2. Mitt webbhotell kör alla sina ”shared hosts” som virtuella maskiner eller i chroot-miljö?
3. Mitt webbhotell kör en automatisk backup av mina sidor och min databas med täta och
jämna mellanrum?
4. Denna backup förvaras på en annan maskin än den där min webbplats ligger?
5. Mitt webbhotell har redundanta linor till sitt serverrum?
6. Mitt webbhotell har fungerande rutiner att meddela mig om deras tjänster ligger nere
eller om mitt konto håller på att övertrasseras gällande bandbredd eller datalagring?
Alla webbhotell har inte installerat stödet rätt för tidszoner i MySQL. Om du behöver göra
det själv (på din egen dator), så sök på webben efter frasen ”Populate timezone tables
mysql”.
19.6 SSL
1. All trafik som är känslig går över förbindelser som är krypterade från start till slut?
2. Eventuella växlingar mellan krypterad och okrypterad förbindelse är konskevent, tydlig
och motiverad?
66
© THELIN LÄROMEDEL & LARS GUNTHER 2013
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
20
© THELIN LÄROMEDEL & LARS GUNTHER 2013
67
WEBBSERVERPROGRAMMERING 1 - LÄROBOK
INDEX
68
© THELIN LÄROMEDEL & LARS GUNTHER 2013