INF130 Datahåndtering og analyse Visualisering av data på web Applikasjonsutvikling Applikasjonsutvikling mot web Databaseapplikasjoner Informasjonssystemer Arkitektur PHP = PHP Hypertext Processor PHP og HTML Grunnleggende konstruksjoner (variabler, løkker, valg, ) Tabeller og assosiative tabeller Behandle skjemadata (HTML Forms) Representere databasetabeller som assosiative matriser PHP og MySQL Etablere og lukke databaseforbindelser Utføre SQL-spørringer Behandle spørreresultater Pensum: Kapittel 12 og 13 Informasjonssystemer En database er en logisk samling av data. Et databasesystem er en database administrert av et databasehåndteringssystem (DBHS). En applikasjon er et program utviklet for en bestemt anvendelse. Et informasjonssystem består av en samling ressurser for å samle inn, behandle, overføre, søke etter og presentere informasjon som blir brukt i en virksomhet. Mer konkret: Informasjonssystem=Databasesystem +Applikasjoner En databaseapplikasjon er en applikasjon som bruker et databasesystem for lagring av data. INF130 Applikasjonsutvikling mot web 1
Databaseklienter i et nettverk q Brukere jobber med databasen fra klientmaskiner. q Databaseapplikasjonen er kanskje installert på hver enkelt maskin. Web-applikasjoner q Web-applikasjoner «kjører i nettleseren». q Ikke behov for installasjon av klientapplikasjoner (typisk kun HTML på klientsiden). Arkitektur for web-løsninger Eksempelvis laget med: Brukergrensesnitt Forretningslogikk Dataaksess HTML, JavaScript PHP Lagrede rutiner q Fysisk er en web-applikasjon fordelt på flere maskiner (database server, web server, klient) q Logisk sett er den ofte bygd opp fra tre «lag» som vist over. q De ulike lagene kan være programmert med forskjellige språk. INF130 Applikasjonsutvikling mot web 2
Statiske web-sider HTML GET fil.html Internett HTTP fil.html Web server (web-klient) Dynamiske web-sider fil.php (web-klient) HTML POST fil.php HTTP Internett Web server + PHP-motor Databasedrevne nettsteder Web server + PHP-motor fil.php HTML POST fil.php HTTP SQL Spørreresultat Internett (web-klient) Databaseserver INF130 Applikasjonsutvikling mot web 3
Program på databasetjeneren Web server + PHP-motor fil.php HTML POST fil.php HTTP Kall Respons Internett (web-klient) Databaseserver Utførelse av lagrede rutiner prog.sql Prosessering på klientsiden fil.php (web-klient) HTML POST fil.php + JavaScript HTTP Internett Web server + PHP-motor AJAX «interaktive web-applikasjoner» + JavaScript Web server + PHP-motor HTTP request XML HTTP request XML tid HTTP request XML tid INF130 Applikasjonsutvikling mot web 4
Web server Web-services Web server fil2.java fil1.php fil3.php XML SOAP Internett HTTP SQL Spørreresultat (web-klient) Databaseserver Internett og web Lokalnett Lokalnett Lokalnett Internett Ruter Lokalnett Internett = et globalt nett av nettverk Web er en anvendelse av internett HTML og HTTP html head body title h1 p HTML (HyperText Markup Language) Elementer, attributter, startmerke, stoppmerke HTML-dokumenter er hierarkisk bygd opp HTTP (HyperText Transfer Protocol) Protokoll = en samling regler HTTP-forespørsel (GET, POST) og HTTP-respons (HTML-dok) a a INF130 Applikasjonsutvikling mot web 5
Web-tjenere, nettlesere og URLer q Opprinnelig var web en samling av kryssrefererende HTMLdokumenter. q Web-tjenere og nettlesere kommuniserer i henhold til en (tilstandsløs) klient/tjener-arkitektur. www.hobbyhus.no Web-tjener fil1.htm En URL (Uniform Resource Locator) er en måte å referere web-ressurser (f.eks. HTML-dokumenter) på. http://www.startsiden.no/musikk/musikksjangere/jazz/index.html protokoll domenenavn katalogsti filnavn HTML-dokumenter og PHPskript www.hobbyhus.no Web-tjener side1.htm PHP-tolker side2.php HTML-dokumenter blir sendt direkte til nettleseren. PHP-skript blir sendt til en PHP-tolker for utførelse. Utdata som PHP-skriptet produserer blir sendt til nettleseren. Det betyr at klient-maskinen ikke ser PHP-koden. Web-løsninger programmert med PHP krever ikke installasjon av programvare på klienten; en standard nettleser er nok. XAMPP Åpen kildekode Ferdigkompilert løsning for Windows XAMPP 1. Apache (www.apache.org) Sjekk localhost 2. MySQL 5.0 (www.mysql.com) Windows installer 3. PHP 5 (www.php.net) Last ned kompilert Windows-versjon Konfigurering Apache styrefil: httpd.conf PHP styrefil: php.ini Pakkeløsning WAMP (AMP on Windows) http://www.wampserver.com Enkel installasjon Meny: Starte/stoppe tjenester, MySQL-konsoll, tillegg, styrefiler INF130 Applikasjonsutvikling mot web 6
Dynamiske web-sider med PHP HTML-skjema Typisk oppsett Skjemadata PHP utdata (HTML) Web-tjener PHP-motor Apache + PHP + MySQL + JavaScript skript.php SQL DBHS Database HTML Hyper Text Markup Language en formaterer tekst skrevet i et HTML format Vi går gjennom HTML prinsippene fra http://www.w3schools.com/html/default.asp HTML struktur http://www.w3schools.com/html/html_intro.asp INF130 Applikasjonsutvikling mot web 7
PHP Skript for å formatere HTML Vi går gjennom PHP prinsippene fra http://www.w3schools.com/php/default.asp Den grunnleggende idéen Et typisk PHP-skript: 1. Motta og behandle skjemadata fra bruker. 2. Bruk skjemadata for å lage en SQL-spørring mot databasen. 4. Bruk spørreresultat (3) for å generere en ny HTML-side. 1 skript.php 2 Database 4 3 PHP web-applikasjoner: Tenk at hver nettside blir generert av ett PHP-skript (forenkling). Nettsidene er dynamiske fordi de er basert på skjemadata fra bruker og innholdet i databasen (som jo endrer seg ). Hver brukerinteraksjon i nettleseren går «innom» webtjeneren (og et PHP-skript): forespørsel respons forespørsel respons Hei web! PHP-koden plasseres mellom <?php og?> <html> <body> <?php print '<h1>hei web!</h1>';?> </body> </html> Denne blandingen av HTML og kode er karakteristisk for PHP (og flere andre skriptspråk). For eksempel Java Server Faces prøver å skille presentasjon og logikk klarere fra hverandre! Lagrer koden i hei.php og kopier ut på web-tjeneren med WinSCP. Åpner nettleseren på side http://www.xyz.no/hei.php WAMP på hjemme-pc: Lagrer PHP-filen på C:\<wamp-rot>\www\hei.php Åpner nettleseren på http://localhost/hei.php Slipper kopiering (kun lagre+ «refresh» i nettleseren) localhost: Bruker egen maskin som web-tjener (og web-klient) INF130 Applikasjonsutvikling mot web 8
Alternativ løsning Her blir det enda mer tydelig at nettsiden som blir levert er utdata fra et program (PHP-skriptet): <?php print '<html>'; print '<body>'; print '<h1>hei web!</h1>'; print '</body>'; print '</html>';?> Hva skjer på forrige lysark? PHP-motoren utfører PHP-skriptet, og «fletter» HTML-koden (utenfor PHP-taggene) med utdata fra skriptet. Mulig å ha flere «HTML-bolker» og «PHP-bolker» i samme skript (man går da ut og inn av «PHPmodus»). Variabler Alle variabelnavn starter med $ <html> <body> <?php $navn = 'Ola'; print '<h1>hei '. $navn. '</h1>';?> </body> </html> Punktum slår sammen tekstverdier Simulere input fra bruker Lagre denne filen som areal.php <html> <body> <?php $side = $_GET['txt_side']; $areal = $side * $side; print '<h1>areal: '. $areal. '</h1>';?> </body> </html> Kopier filen ut på ditt område på web-tjeneren home.hit.no Test i nettleseren http://www.xyz.no/areal.php?txt_side=5 Hva vises på nettsiden? INF130 Applikasjonsutvikling mot web 9
Enkle og doble apostrofer En tekst omsluttet av doble apostrofer kan inneholde variabler PHP-motoren erstatter slike variabler med sin verdi. Det er altså Ola og ikke $navn som blir vist på nettsiden (under). Doble apostrofer er «behagelige», enkle er litt mer effektive. <html> <body> <?php $navn = 'Ola'; print '<h1>hei '. $navn. '</h1>'; print "<h1>hei $navn </h1>";?> </body> </html> En vanlig feil Man glemmer at variabelnavn starter med $ <html> <body> <?php $navn = 'Ola'; print '<h1>hei '. navn. '</h1>';?> </body> </html> Det blir skrevet ut en feilmelding på nettsiden Les feilmeldingen og legg merke til linjenummeret. Årsaken til Feil på linje 57 kan skyldes feil på linje 12! Linjeskift i kildekoden Den synlige nettsiden er det viktigste, men I forbindelse med feilretting er det imidlertid behagelig om også kildekoden ser bra ut. \n produserer linjeskift (\t for tabulator ) <?php $navn = 'Ola'; print '<html>\n'; print '<body>\n'; print '<h1>hei '. $navn. '</h1>\n'; print '</body>\n'; print '</html>\n';?> INF130 Applikasjonsutvikling mot web 10
Datatyper Det er ikke nødvendig å deklarere variabler i PHP Datatyper boolean, integer, float, string array, object (og et par til) PHP-tolkeren utleder datatypen fra sammenhengen $et_heltall = 3; $et_kommatall = 3.14; $en_tekst = 'Ola'; $x = $et_heltall + 4; Operatorer Aritmetiske operatorer + - * / % 10%3 er lik 1 Sammenligningsoperatorer > >= ==!= < <=== betyr likhet === lik og samme type!== ulik og forskjellig type Inkrement og dekrement ++ -- +1 og -1 Logiske operatorer &&! og eller ikke Noen spesielle operatorer..= slå sammen tekst legg til tekst += *= $x+=2; det samme som $x=$x+2; Innebygde funksjoner Tekststrenger str_pad, strlen, substr, substr_replace, trim, ucfirst, Dato og tid date, getdate, gettimeofday, strtotime, Matematikk abs, ceil, cos, exp, floor, log, pi, rand, round, sin, sqrt, tan, Eksempler $s = substr('abcdef', 1, 3); // bcd $today = getdate(); $avst = sqrt(exp($x2-$x1,2) + exp($y2-$y1,2)); INF130 Applikasjonsutvikling mot web 11
Konvertering Skjemadata er i utgangspunktet tekst $side = $_GET['txt_side']; // fra skjema $areal = $side * $side; Implisitt konvertering $tall = '2' + '2'; // $tall blir lik 4 Eksplisitt konvertering (typetvang, type casting) $tall = (int) '85'; Funksjoner for å avlese datatype is_int($tall), is_numeric($side), Presentasjon av tall Parametre til funksjonen number_format: Antall desimaler Tegn for desimalpunktum Tusenskilletegn $pris = 123456.789; print( number_format($pris, 2, ',', ' ') ); Resultat: 123 456,79 Valgsetninger Bruker skriver inn alder - programmet skriver ut pris $alder = $_GET['alder']; // Fra skjema $pris = 80; // Full pris if ($alder < 7) { $pris = 0; // [0..7> går gratis else { if ($alder <= 12 $alder > 67) $pris = $pris * 0.5; // Halv pris print ('Pris: '. $pris); INF130 Applikasjonsutvikling mot web 12
While-løkker Bruker skriver inn øvre grense (positivt heltall!) programmet skriver ut summen av tallene fra 1..max $max = $_GET['max']; // Fra skjema $tall = 1; $sum = 0; while ($tall <= $max) { $sum = $sum + $tall; $tall = $tall + 1; // Alternativt $tall++; print('sum 1..'. $max. '='. $sum); Tabeller i PHP Tabeller egner seg for gjennomløp med for-løkker // Nedbør (mm) pr. dag i en gitt uke $nedboer = array(3,0,0,23,0,17,4); $antall = sizeof($nedboer); // 7 elementer for (int $i=0; $i<$antall; $i++) { $sum += $nedboer[$i]; // Merk += $snitt = $sum / $antall; print('totalt: '. $sum. ' snitt: '. $snitt); Gjennomløp med foreach Hvis vi skal skrive ut alle verdiene i en tabell Trenger ikke å vite posisjonene foreach-løkker er da ofte en enklere løsning enn for-løkker For å produsere en punktliste må vi Skrive ut <ul> helt først og </ul> helt til slutt Så må vi omslutte hver verdi med <li> og </li> $tabell = array(3,0,0,23,0,17,4); print '<ul>'; foreach ($tabell as $enverdi) { print '<li>'. $enverdi. '</li>'; print '</ul>'; INF130 Applikasjonsutvikling mot web 13
Produsere en HTML-tabell For å skrive ut en HTML-tabell må vi nøste to løkker $tab1 = array(1,2,3,4,5); $tab2 = array(1,2,3,4,5,6,7); print '<table>'; foreach ($tab1 as $v1) { print '<tr>'; foreach ($tab2 as $v2) { print '<td>'. $v1*$v2. '<td>'; print '</tr>'; print '</table>'; Hvordan ser resultatet ut? Assosiative tabeller Vanlige tabeller blir indeksert med heltall $tab[0], $tab[1], $tab[2], I assosiative tabeller kan vi velge indeksering $nedboer = array ( "mandag" => 3, "tirsdag" => 0, "onsdag" => 0, "torsdag" => 23, "fredag" => 0, "lørdag" => 17, "søndag" => 4 ); $man = $nedboer["mandag"]; // slår opp $nedboer["mandag"] += 2; // oppdaterer Tenk på assosiative tabeller som «funksjoner» (her fra dag til mm) foreach-løkke Kan gjennomløpe alle elementene i en assosiativ tabell med en slags «mønstergjenkjenningsteknikk» $sum = 0; $nedboer = array( ); // Se forrige lysark foreach ($nedboer as $ukedag => $mm) { print($ukedag. " ". $mm. " mm"); $sum += $mm; print("totalt ". $sum. " mm nedbør"); Tenk slik: En assosiativ tabell er en «mapping» fra nøkkel til verdi I vårt eksempel fra ukedager til nedbørsmengde Utfører løkkekroppen for hvert par nøkkel => verdi INF130 Applikasjonsutvikling mot web 14
isset og array_key_exists Finnes en bestemt nøkkel i en assosiativ matrise? $d = "juledag"; if (!array_key_exists($d, $nedboer)) print("ukjent ukedag"); Har vi fått inndata fra bruker? if (! isset($_get["txtantall"]) ) print("du må skrive et tall!"); HTML-skjema <form method="get" action="skjemabehandler.php"> <p>navn: <input type="text" name="navn" size="20"> </p> <p> <input type="submit" value="søk" name="sok"> <input type="reset" value="rensk" name="rensk"> </p> </form> Behandle skjemadata Navnet brukeren skriver inn i nettside 1 blir altså <html> vist fram i nettside 2. <body> <h1>kundedata</h1> <?php $fornavn = $_GET["navn"]; print("<p>fornavn: ". $fornavn. "</p>");?> </body> </html> $_GET inneholder skjemadata når metode GET er brukt $_GET er en assosiativ tabell (parameter => verdi) Med GET er skjemadata synlig i URLen (?navn=kari) Kan ha bokmerker til «nettside med skjemadata» Kan teste nettsider uten å lage skjema INF130 Applikasjonsutvikling mot web 15
Metode POST Fordeler med POST Kan overføre større datamengder enn ved GET Skjemadata er ikke synlig i URLen Hindrer at andre får tak i sensitiv informasjon ved å se på skjermen NB! Skjemadata blir ikke kryptert verken med GET eller POST Bruker nok vanligvis Hvordan? POST i en HTML Form. <form method="post" action="skjemabehandler.php"> <input type="text" name="navn" size="20"> <input type="submit" value="søk" name="sok"> </form> I skjemabehandler.php: $fornavn = $_POST["navn"]; $_GET, $_POST og $_REQUEST Skjemadata blir altså overført i en assosiativ matrise Merk for øvrig at passord ikke blir kryptert $_GET = array ( "brukernavn" => "Ola", "passord" => "Hemmelig" ) De superglobale matrisene $_GET : skjemadata overført med metode GET $_POST : skjemadata overført med metode POST $_COOKIES : informasjonskapsler $_REQUEST : summen av $_GET, $_POST og $_COOKIES Bruk av $_REQUEST POST-forespørsel: <form method="post" action="skjemabehandler.php"> <input type="text" name="navn" size="20"> <input type="submit" value="søk" name="sok"> </form> GET-forespørsel: http://.../skjemabehandler.php?navn=ola Samme skript kan behandle begge typer av forespørsler: $fornavn = $_REQUEST["navn"]; INF130 Applikasjonsutvikling mot web 16
Databasetabeller som assosiative tabeller En databasetabell består av et antall rader: $dbtab = array($rad1,$rad2,$rad3); Hver rad kan håndteres som en «mapping» fra kolonnenavn til verdi: $rad1 = array("nr"=>1, "navn"=>"per"); En databasetabell er altså en tabell av slike «mapping»- tabeller: $dbtab = array( array("nr"=>1, "navn"=>"per"), array(), ); Dette er i hvert fall én måte å representere databasetabeller på i PHP... Databasedrevne webløsninger med PHP HTML-skjema Skjemadata 4 1 PHP utdata (HTML) Web-tjener PHP-motor 2 3 Spørreresultat SQL DBHS Database Web-tjener er «tjener» mot nettleser og «klient» mot DBHS Skjemadata blir til SQL blir til spørreresultat blir til HTML Opprette databaseforbindelse For å koble opp til en MySQL-tjener: Adressen til tjeneren (evt. localhost) Brukernavn Passord En MySQL-tjener kan inneholde flere databaser: Må velge database $forbindelse = mysql_connect("localhost","bruker","passord") ; mysql_select_db("test"); Lukke forbindelsen til databasen: mysql_close( $forbindelse ); // mysql_free_result INF130 Applikasjonsutvikling mot web 17
Utføre SELECT-spørringer Sender med SQL-spørringen som parameter til mysql_query: $sql = "SELECT * FROM Vare;"; $resultat = mysql_query( $sql ); Antall returnerte rader: $antall = mysql_num_rows( $resultat ); Hva inneholder $resultat? $resultat er av datatype resource; referanse til en ekstern ressurs Inneholder hele spørreresultatet Kan løpe gjennom spørreresultat med en løkke og hente ut verdier Databaseforbindelse I kallet på mysql_query så er det underforstått at vi skal bruke databaseforbindelsen $forbindelse: $forbindelse = mysql_connect("localhost","bruker","passord"); mysql_select_db("test"); $sql = "SELECT * FROM Vare;"; $resultat = mysql_query($sql); Vi kan gjøre dette eksplisitt: $resultat = mysql_query($sql, $forbindelse); Dette gjelder flere av MySQL-funksjonen i PHP. Bygge SQL-spørringer fra skjemadata Lagre skjemadata i PHP-variable: $sok = $_REQUEST["txtSok"]; Bygg SQL merk enkle og doble apostrofer og blanke tegn! $sql = "SELECT * FROM Vare ". "WHERE Betegnelse LIKE '". $sok. "%';"; Test: Skriv ut SQL-koden! print("<p>testutskrift:". $sql. "</p>"); INF130 Applikasjonsutvikling mot web 18
Behandle spørreresultater I Anta $resultat er et spørreresultat med en kolonne Betegnelse: $linje = mysql_fetch_array($resultat, MYSQL_ASSOC); while ( $linje ) { $navn = $linje["betegnelse"]; print( $navn. "<br>"); $linje = mysql_fetch_array($resultat, MYSQL_ASSOC); Alternativer: MYSQL_NUM, MYSQL_BOTH Behandle spørreresultater II Det er ikke nødvendig å vite navnet på kolonnene: $linje=mysql_fetch_array($res, MYSQL_ASSOC)); while ($linje) { foreach ($linje as $verdi) { print($verdi. " "); print("<br>"); $linje=mysql_fetch_array($res, MYSQL_ASSOC)); Fra spørreresultat til HTMLtabell Generelt blir dette en nøstet løkke Skriv ut <table> Hent første rad Skriv ut <tr> Hent første verdi Skriv ut <td> Skriv ut første verdi Skriv ut </td> (verdi 2, verdi 3, ) Skriv ut </tr> (rad 2, rad 3, ) Skriv ut </table> INF130 Applikasjonsutvikling mot web 19
UPDATE og DELETE Gir ikke et spørreresultat, men vi kan finne ut hvor mange rader som ble berørt: $sql = "DELETE FROM Vare;"; $resultat = mysql_query( $sql ); if ($resultat) print(mysql_affected_rows(). " rader ble slettet!"); else print("noe gikk galt!"); UPDATE og DELETE berører samtlige rader hvis vi ikke legger på en WHERE-betingelse! INSERT Setter som regel inn 1 rad basert på skjemadata: $varekode = $_REQUEST["varekode"]; $betegnelse = $_REQUEST["betegnelse"]; $sql = "INSERT INTO Vare(Varekode,Betegnelse) ". "VALUES (". $varekode. "'". $betegnelse. "'". ");"; $resultat = mysql_query( $sql ); Merk: Apostrofer rundt tekstverdier, men ikke rundt tall Øvrige kolonner i den nye raden blir satt til NULL Autonummerering I MySQL angis autonummerering som en kolonne-egenskap: CREATE TABLE Ansatt ( AnsNr INTEGER AUTO_INCREMENT, ); Kolonner som er autonummererte tas ikke med i INSERT INSERT INTO Ansatt(Fornavn, Etternavn) VALUES ('Per', 'Hansen'); Hvordan få tak i sist genererte ansattnr: mysql_query($sql); $sisteansnr = mysql_insert_id(); INF130 Applikasjonsutvikling mot web 20
Øvinger Oppgave 7 Et selvstudium INF130 Applikasjonsutvikling mot web 21