5.6. Hvordan laver vi koden i PHP

I dette afsnit afslører jeg, hvordan vores eksempel kodes i PHP. Gennemgangen struktures på følgende måde:

Først viser jeg kildeteksten, hvorefter jeg vil gennemgå den. Jeg antager, at du er bekendt med HTML, men har ingen eller næsten igen erfaring med PHP. Hvis du ikke har erfaring med HTML, vil jeg råde dig til, at hente denne viden et andet sted, inden du læser videre. Eksemplerne er dog ikke sværere end at man med et minimalt kendskab til HTML, vil kunne følge med i gennemgangen.

5.6.1. Login

Her har du koden til login billedet. Bemærk, at det er skrevet i rent HTML.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
     "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
        <TITLE>Login på Friheden - vinduet til PHP's forunderlige verdenen</TITLE>
<META name="Generator" content="Stone's WebWriter 3">
</HEAD>
<BODY bgcolor="#999999" text="#000000" link="#0000FF" vlink="#660066"
  alink="#FF0000">
<CENTER>
<H1>Login på Friheden</H1>
<H2>Dit vindue til PHP</H2>
<HR>
<FORM action="login.php" method="POST" name="login">
Brugernavn: <INPUT type="text" name="user"><BR>
Password:   <INPUT type="password" name="password">
<P><INPUT type="submit" value="Log on" name="submit">
</FORM>
</CENTER>
<BR>
<P><HR>
<CENTER><FONT face="Times New Roman" size="-2">
Copyright © Michael Rasmussen</FONT></CENTER>
</BODY>
</HTML>

Brugeren indtaster sit brugernavn og password.

5.6.2. Brugervalidering

Her se koden for valideringen af brugerinput:


<?php
  require("Config.php");
  /*
  Denne fil indeholder definitionen på alle databasevariable. Variabelnavnene er skrevet med stort,
  og første tegn begynder med "_". Henvisningen tilføjes i starten af alle filer, der tilgår MySQL.
  */

  $link = @mysql_connect(_MYSQL_SERVER_NAME, _MYSQL_USER_NAME, _MYSQL_PASSWORD);
  if ($link == 0) {
     header("Location: Fejl.php?kode=1");
     exit;
  }

  mysql_selectdb(_MYSQL_DATABASE_NAME, $link);

  $password = md5($password);
  $SQLQuery = "SELECT Brugernavn FROM Users ";
  $SQLQuery .= "WHERE brugernavn='$user' and ";
  $SQLQuery .= "password='$password'";
  $result = mysql_query($SQLQuery);
  if ($result == 0) {
     header("Location: Fejl.php?kode=2");
     exit;
  }
  else{
       if (mysql_fetch_array($result)){
           $bruger_id = mysql_result($result,'Brugernavn');
           $session_id = md5(uniqid(rand()));
           $SQLQuery = "INSERT INTO Session (Brugernavn, SessionID, SessionDato) ";
           $SQLQuery .= "VALUES ('$bruger_id', '$session_id', '" . date("Y-m-d H:i:s") . "')";
           $result = mysql_query($SQLQuery);
           if ($result == 0) {
                header("Location: Fejl.php?kode=3");
                exit;
           }
           mysql_close($link);
           header("Location: Velkommen.php?sessionid=$session_id");
           exit;
       }
  else header("Location: Fejl.php?kode=4");
  }
?>

Først skal vi erklære vores databasevariable. Dette foregår i filen Configure.php [1]. Herefter skal vi skabe en forbindelse til MySQL, og dette gøres med funktionen mysql_connect( MySQL server, MySQL brugernavn, MySQL password). Hvis alt går vel, for vi returneret en handle til database serveren. For at finde ud af om alt gik godt, laver vi en test på den returnerede handle. Har den en værdi forskellig fra 0, er alt i den skønneste orden, ellers er der opstået en fejl. Til at håndtere fejlmeddelelser til brugerne har jeg skrevet en fil, som udskriver den rigtige fejlmeddelelse baseret på en medsendt kode. Dette har jeg gjort for at holde styr på alle fejlmeddelelser, og samtidig sikrer man sig også mod at udskrive en forskellig fejlmeddelelse hver gang. Efter vi har fået forbindelse til MySQL, forestår blot at bede den om at aktivere vores database. Dette gøres med funktionen mysql_selectdb(MySQL database, databasehandle) .

Vi har nu fået forbindelse til databasen, og kan herefter begynde at trække oplysninger ud fra den. Det første vi skal gøre, er, at få krypteret det indtastede password med MD5. Herefter skal vi blot bede om at få brugernavnet i tabellen Users, hvis password er lig med, det indtastede. Det gøres med funktionen mysql_query(SQL forespørgsel) [2]. Hvis det returnerede resultat er <> 0, er der opstået en fejl, i modsat fald får vi en handle til de(n) række(r), som opfylder vores betingelser - SQL forespørgslen. Da vi ved, at vi kun vil få returneret en række, behøver vi kun at læse indholdet af den første række. Til det formål benytter vi os af funktionen mysql_fetch_array(handle) [3]. Havde vi kunnet få flere rækker returneret, måtte vi for at se alle rækkerne, benytte os af en løkkestruktur [4]. Funktionen returnerer den første række i vores handle, og de enkelte felter hentes med funktionen mysql_result(handle, feltnavn).

Det vi mangler, er blot at generere et SessionID og indsætte det i tabellen Sessions sammen med vores brugernavn. For at generere et SessionID skal vi bruge funktionen uniqid(værdi). For at gøre det endnu mere tilfældigt bruger jeg funktionen rand([min [, max]]). Da jeg ikke har nogen krav til uddata, bruger jeg funktionen uden angivelse af min og max. Det returnerede tal skal nu konverteres til et SessionID, og derfor sender vi resultatet fra uniqid til funktionen MD5. At jeg bruger kryptering her, hænger sammen med, at antallet af mulige værdier SessionID kan have bliver forøget fra (9+31^10) til (32^37). Det er derfor meget sværere at gætte SessionID's værdi, og hvis du udvider systemet med en funktion, som rydder op i Session-tabellen, så vil det være næsten umuligt at gætte en anden brugers SessionID.

Vi har nu et brugernavn og et SessionID, og vi kan derfor tildele det til vores ny besøgende, og indsætte vedkommende i tabellen over tildelte sessions. Herefter forestår kun at lukke vores forbindelse til MySQL, og sende brugeren videre til den første side sammen med personens tildelte SessionsID. Dette gøres med kommandoen header("Location: Velkommen.php?sessionid=$session_id");

5.6.3. Hvordan henter vi information på baggrund af et SessionID

For at hente oplysninger ud af databasen, baseret på et aktuelt SessionID, bruges følgende fremgangsmåde:


<?php
  include("session.php");

  if ($SessionID == "") {
       header("Location: login.html");
       exit;
  }
  $SQLQuery = "SELECT Brugernavn FROM Session WHERE SessionID = '$SessionID'";
  $result = mysql_query($SQLQuery);
  if ($result == 0) {
    header("Location: Fejl.php?kode=2");
    exit;
  }
  else {
    $field = mysql_fetch_array($result);
    $bruger_id = $field['Brugernavn'];
  };

  $SQLQuery = "SELECT Brugernavn, Navn, Email, Status, Oprettet from Users ";
  $SQLQuery .= "WHERE brugernavn='$bruger_id'";
  $result = mysql_query($SQLQuery);
  if ($result == 0) {
    header("Location: Fejl.php?kode=2");
    exit;
  }
  else {
    $field = mysql_fetch_row($result);
    $bruger = $field['Brugernavn'];
    $navn = $field['Navn'];
    $email = $field['Email'];
    $status = $field['Status'];
    $oprettet = $field['Oprettet'];
  }
?>
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN \">
<HTML>
<HEAD>
        <TITLE>Websted Friheden</TITLE>
<META name=Generator content=Stone's WebWriter 3>
</HEAD>
<BODY bgcolor="#999999" text=#000000 link=#0000FF vlink=#660066 alink=#FF0000>
<BR><BR><BR><BR>
<CENTER>
<H2>Hvilke oplysninger har vi registreret om den pågældende person</H2>
<TABLE border=1 bgcolor=#CCFFFF>
<TH colspan="2" bgcolor="YELLOW">Følgende er registreret om <?php print "$bruger" ?></TH>
</TR>
<TR>
        <TD>Navn</TD>
        <TD><?php echo "$navn" ?></TD>
</TR>
<TR>
        <TD>Email adresse</TD>
        <TD><?php echo "$email" ?></TD>
</TR>
<TR>
        <TD>Status</TD>
        <TD><?php echo "$status" ?></TD>
</TR>
<TR>
        <TD>Oprettet</TD>
        <TD><?php echo "$oprettet" ?></TD>
</TR>
</TABLE>
<BR>
<BR>
<?php
if ($bruger == 'admin'){
    print
    "<BR>
    <A href='NyBruger.php?sessionid=$SessionID'>Opret ny bruger</A>";
}
?>
</CENTER>
<BR>
<P><HR>
<CENTER><FONT face="Times New Roman" size="-2">
Copyright © Michael Rasmussen</FONT></CENTER>
</BODY>
</HTML>
  

Vi er nu nået til det punkt, hvor vi skal til at se resultatet af vores anstrengelser. Det første vi selvfølgelig skal gøre, er, at kontrollere om vores bruger har logget sig ind. Har han ikke det, bliver han sendt til login siden. Denne kontrol foregår i filen session.php, og resultatet af kontrollen har to udfald: Vi har en godkendt bruger - 1) SessionID medsendt, 2) SessionID er valid, eller vi har en ikke godkendt bruger - 1) SessionID er ikke medsendt, 2) SessionID er ikke valid. Mere om denne fil senere. For nu antager vi blot, at vi har at gøre med en godkendt bruger.

I filen session.php fandt vi ud af, om brugeren var godkendt. Ved samme lejlighed hentede vi samtidig denne brugers brugernavn, og på baggrund af dette brugernavn har vi nu mulighed for, at hente de resterende oplysninger i tabellen Users. Opbygningen af forespørgslerne og udtrækningen af informationerne foregår på præcis samme måde, som beskrevet under Brugervalidering.

Her kommer den lovede gennemgang af filen session.php. Først kommer kilden:


<?php
  include("Config.php");

  $link = mysql_connect(_MYSQL_SERVER_NAME, _MYSQL_USER_NAME, _MYSQL_PASSWORD);
  if ($link == 0) {
     $SessionID = "";
  }
  else {
     mysql_selectdb(_MYSQL_DATABASE_NAME, $link);
     if (!isset($SessionID) or ($SessionID == "")) {
     $SessionID = "";
      }
     else {
        $SQLQuery = "SELECT Brugernavn from Session ";
        $SQLQuery .= "WHERE sessionid='$SessionID'";
        $result = mysql_query($SQLQuery);
        if ($result == 0) {
             $SessionID = "";
        }
        else {
              if (mysql_fetch_array($result)) {
                  $bruger_id = mysql_result($result,'Brugernavn');
              }
              else {
                   $SessionID = "";
              };
              mysql_free_result($result);
        }
     }
  }
?>

Først undersøges der, om vi kan etablere en forbindelse til databaseserveren. Kan vi ikke det, sættes SessionID = "" - hvis der ikke er forbindelse til databasen, vil vi af sikkerhedsgrunde, ikke tillade login til sikrede sider. Hvis vi kan få etableret en forbindelse, undersøges der, om brugeren har logget sig på - if (!isset($SessionID) or ($SessionID == "")): Hvis SessionID ikke er aktiveret, eller hvis det ikke er tildelt nogen værdi, sættes SessionID = "". Hvis SessionID er tildelt en værdi, skal vi hente, det tilknyttede brugernavn. Hvis vi får en tom række tilbage, er det fordi, der ikke er blevet medsendt et valid SessionID, og derfor sættes SessionID = "". Inden vi afslutter, frigives vores handle.

Slutbemærkning:

[1]

<?php
   //Database configs
   define("_MYSQL_SERVER_NAME", "localhost");
   define("_MYSQL_USER_NAME", "webuser");
   define("_MYSQL_PASSWORD", "WebVer1.00");
   define("_MYSQL_DATABASE_NAME", "friheden");
?>
[2]

Et glimrende opslagsværk, til den overkommelige pris af 69 kr, der kan købes i alle boghandler, er et lille hæfte fra IDG Forlag. (Rolland, 1999: Start på SQL)

[3]

Af uforklarlige årsager fungerer funktionen mysql_fetch_row(handle) ikke, som den skal, når man afvikler commandoen i PHP på en Windows-server - fejlen opstår, hvis man skal hente oplysninger fra flere felter i vores uddata, så derfor har jeg af kombatilitetshensyn valgt, konsekvent at benytte mig af funktionen mysql_fetch_array(handle)

[4]

F.eks. while (mysql_fetch_array(result))