wiki.phpfreakz.nl
Aanmelden Artikel Overleg Bewerk Geschiedenis Go to the site toolbox

Het Wiel Uitgevonden:Nieuwssysteem

--Taco 27 apr 2009 23:25 (CEST)

In deze tutorial bouwen we stap voor stap een nieuwssysteem. Ik neem aan dat je de vorige tutorials hebt gelezen? Mooi! Dan heb je een hoop dingen geleerd, maar nog niets gebouwd voor je eigen site. Tijd om daar verandering in te brengen! Eerst even een inleiding in databases, want dat is waar alles op deze pagina om draait.

Inhoud

Databases

Informatie op je website kan je op allerlei manieren opslaan: Comma-Separated Values, een XML-bestand, plain text. De meestgebruikte en handigste manier is echter een database. Hierin kan je data opslaan en op een snelle, intelligente manier ophalen. We gaan een SQL-database gebruiken in deze tutorial. Omdat MySQL-databases het meeste voorkomen, ga ik hiervan uit. Mocht je echter de kans hebben andere databases te kiezen, maak deze keuze dan weloverwogen en goed ingelicht! Zie bijvoorbeeld Databases vergeleken op deze wiki.

Databases kunnen prima met PHP communiceren maar staan er in zeker zin los van. Het zijn verschillende processen op de server en je zult dus een communicatieverbinding moeten openen, vóór je aan de slag kunt. Hiervoor heb je een adres nodig, een gebruikersnaam en een wachtwoord. Ik neem even aan dat je deze hebt en gebruik voor gebruikersnaam 'root' met als wachtwoord een lege string (dit zijn de standaardinstellingen).

De nieuwstabel

Een database bestaat (onder andere, maar dat is voor veel later) uit tabellen. Om de nieuwsberichten in een database op te kunnen slaan, maken we een 'nieuws'-tabel aan. Hiervoor kan je software gebruiken, zoals phpMyAdmin. Alternatief kan het via de command-line, of maak je er een speciaal PHP-bestandje voor aan. In phpMyAdmin kies je je database (zeg, pfz_hwu), klik je op 'SQL' voor direct invoer en voer je in:

CREATE TABLE nieuws (
  nieuws_id    INT          NOT NULL  AUTO_INCREMENT  PRIMARY KEY ,
  titel        VARCHAR(255) NOT NULL ,
  bericht      TEXT         NOT NULL ,
  geplaatstop  DATETIME     NOT NULL 
);

Al onze nieuwsberichten kunnen nu vier gegevens hebben: een uniek, automatisch toegevoegd nieuws_id, zodat we handig berichten kunnen benoemen. Een titel en het bericht zelf, zodat we daadwerkelijk iets kunnen melden. Een een veld waarin we opslaan wanneer het bericht geplaatst is, altijd interessant.

Berichten invoeren

Allereerst zullen we berichten in moeten kunnen voeren. Dit is niet veel meer dan een formulier, dus zonder veel poespas pak ik de code van Het Wiel Uitgevonden:Formulieren! We hoeven alleen maar de velden aan te passen; om precies te zijn hebben we één text-input en één textarea nodig voor de titel en het bericht. Het nummer en de datum hoeft de gebruiker niet in te voeren, natuurlijk. Vervolgens komt er in het stukje 'Gegevens verwerken!' de specifieke code voor de database. Op die manier krijgen we news_insert.php:

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
 
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
  //  Er zijn gegevens verstuurd naar deze pagina! 
 
  //  We gaan de errors in een array bijhouden
  $aErrors = array();
 
  //  We hebben een niet-lege titel nodig
  if ( !isset($_POST['titel']) or trim($_POST['titel'])=='' ) {
    $aErrors['titel'] = 'Geef een titel voor het nieuwsbericht op!';
  }
 
  //  En uiteraard, een niet-leeg bericht
  if ( !isset($_POST['bericht']) or trim($_POST['bericht'])=='' ) {
    $aErrors['bericht'] = 'Voer een bericht in!';
  }
 
  if ( count($aErrors) == 0 ) {
    //  We hebben alle gegevens
 
    //  Maak een verbinding met de database
    $rLink = mysql_connect(
      'localhost',    //  host
      'root',         //  user
      ''              //  password
    );
    //  Controleer of het gelukt is
    if ( $rLink === false ) {
      throw new Exception('Could not connect to database');
    }
 
    //  Selecteer je database
    $bSelected = mysql_select_db( 'pfz_hwu', $rLink );
    //  Controleer of het gelukt is
    if ( $bSelected === false ) {
      throw new Exception('Could not select the database');
    }
 
    //  Construeer een opdracht voor de database
    $sQuery = sprintf("INSERT INTO nieuws  (titel, bericht, geplaatstop)
                       VALUES              ('%s',  '%s',    NOW() )",
                       mysql_real_escape_string( $_POST['titel'] ),
                       mysql_real_escape_string( $_POST['bericht'] ) );
    //  Stuur de opdracht op
    $rResult = mysql_query( $sQuery, $rLink );
    //  Controleer of het gelukt is
    if ( $rResult === false ) {
      throw new Exception(
        'Could not insert news item!'.PHP_EOL.
        'Database returned: '.mysql_error( $rLink ).PHP_EOL.
        'Query was: '.$sQuery
      );
    }
 
    //  Volgende pagina aub. Bijvoorbeeld de overzichtpagina.
    //  Deze link is waarschijnlijk anders voor jouw pagina, dus pas hem aan!
    header('Location: http://localhost/news.php');
    die();
  }
 
}
 
/**************************************************
*  Einde van de verwerking, begin van de uitvoer  *
**************************************************/
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Nieuwsberichten - invoeren</title>
    <style type="text/css">
      .errorlist, .error input, .error textarea{
        border: 1px solid #f00;
        background: #fdd;
      }
      form.cmxform fieldset {
        margin-bottom: 10px;
      }
      form.cmxform legend {
        padding: 0 2px;
        font-weight: bold;
      }
      form.cmxform label {
        display: inline-block;
        line-height: 1.8;
        vertical-align: top;
      }
      form.cmxform fieldset ol {
        margin: 0;
        padding: 0;
      }
      form.cmxform fieldset li {
        list-style: none;
        padding: 5px;
        margin: 0;
      }
      form.cmxform label {
        width: 120px; /* Width of labels */
      }
    </style>
  </head>
  <body>
    <form action="news_insert.php" method="post" class="cmxform">
      <?php
      if ( isset($aErrors) and count($aErrors) > 0 ) {
        print '<ul class="errorlist">';
        foreach ( $aErrors as $error ) {
          print '<li>' . $error . '</li>';
        }
        print '</ul>';
      }
      ?>
      <fieldset>
        <legend>Nieuw bericht</legend>
        <ol>
          <?php echo isset($aErrors['titel']) ? '<li class="error">' : '<li>' ?>
            <label for="titel">Titel</label>
            <input id="titel" name="titel" value="<?php echo isset($_POST['titel']) ? htmlspecialchars($_POST['titel']) : '' ?>" />
          </li>
          <?php echo isset($aErrors['bericht']) ? '<li class="error">' : '<li>' ?>
            <label for="bericht">Bericht</label>
            <textarea id="bericht" name="bericht" cols="60" rows="10"><?php
              echo isset($_POST['bericht']) ? htmlspecialchars($_POST['bericht']) : ''
            ?></textarea>
          </li>
        </ol>
      </fieldset>
      <input type="submit" value="Verstuur" />
    </form>
  </body>
</html>

Probeer het maar eens uit en voeg een paar berichtjes in. Als je zonder klagen wordt doorgestuurd, is het invoeren blijkbaar gelukt. Als je de database kan bekijken in phpMyAdmin, kan je gelijk controleren of dat echt het geval is. Anders moet je even wachten op de volgende stap: het lijstje met nieuwsberichten weergeven

Berichten weergeven

Als het goed is hebben we nu een tabel waar al onze nieuwberichten in staan. Nu willen we graag een overzichtje, zodat mensen kunnen doorklikken naar de juiste nieuwsberichten. Hiervoor zullen we weer verbinding met de database moeten maken. Vervolgens vragen we de database vriendelijk de nieuwsberichten op te hoesten, op volgorde van datum. We zijn alleen geïnteresseerd in de titel en het nieuws_id: als mensen méér willen lezen, moeten ze op de link klikken. Noem het bestand news_all.php en zet dit erin:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Nieuwsberichten - overzicht</title>
    <style type="text/css">
      p.error {
        border: 1px solid #f00;
        background: #fdd;
      }
    </style>
  </head>
  <body>
    <?php
    ini_set('display_errors', 'On');
    error_reporting(E_ALL | E_STRICT);
 
    $aErrors = array();
    //  Maak een verbinding met de database
    $rLink = mysql_connect(
      'localhost',    //  host
      'root',         //  user
      ''              //  password
    );
    //  Controleer of het gelukt is
    if ( $rLink === false ) {
      $aErrors[] = 'De database is onbereikbaar. Probeer het later opnieuw.';
    }
    else {
      //  Selecteer je database
      $bSelected = mysql_select_db( 'pfz_hwu', $rLink );
      //  Controleer of het gelukt is
      if ( $bSelected === false ) {
        $aErrors[] = 'De database is niet geselecteerd. Probeer het later opnieuw.';
      }
      else {
        //  Construeer een opdracht voor de database
        $sQuery = "SELECT   nieuws_id
                   ,        titel
                   FROM     nieuws
                   ORDER BY geplaatstop";
        //  Stuur de opdracht op
        $rResult = mysql_query( $sQuery, $rLink );
        //  Controleer of het gelukt is
        if ( $rResult === false ) {
          $aErrors[] = 'Het is niet gelukt de nieuwsberichten op te halen.';
        }
        elseif ( mysql_num_rows($rResult) == 0 ) {
          $aErrors[] = 'Er zijn geen nieuwsberichten!';
        }
      }
    }
    //  Als er dingen fout zijn gegaan, vertel het
    if ( count($aErrors) > 0 ) {
      echo '<p class="error">';
      foreach ( $aErrors as $sError ) {
        print $sError . '<br />';
      }
      echo '</p>';
    }
    //  Geen fouten? Dan maken we een lijst!
    else {
      echo '<ul>';
      while ( $aBericht = mysql_fetch_assoc( $rResult ) ) {
        //  We moeten vanwege de speciale tekens in de titel htmlspecialchars() gebruiken
        //  Dit zorgt ervoor dat bijvoorbeeld < en " onschadelijk worden gemaakt
        echo '<li>';
        echo '<a href="news_read.php?id='.htmlspecialchars($aBericht['nieuws_id']).'">';
        echo htmlspecialchars($aBericht['titel']);
        echo '</a>';
        echo '</li>' . PHP_EOL;
      }
      echo '</ul>';
    }
    ?>
  </body>
</html>

Ok mooi, nu hebben we een lijstje met nieuwsberichten. Tijd om de losse berichten uit te lezen.

Losse berichten weergeven

Via de link uit het overzicht komen we bij news_read.php. Via de url wordt het id van het nieuwbericht meegegeven. Aan de hand daarvan halen we alle informatie uit de database over dat ene bericht en zetten het op het scherm.

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
 
$aErrors = array();
//  Maak een verbinding met de database
$rLink = mysql_connect(
  'localhost',    //  host
  'root',         //  user
  ''              //  password
);
//  Controleer of het gelukt is
if ( $rLink === false ) {
  $aErrors[] = 'De database is onbereikbaar. Probeer het later opnieuw.';
}
else {
  //  Selecteer je database
  $bSelected = mysql_select_db( 'pfz_hwu', $rLink );
  //  Controleer of het gelukt is
  if ( $bSelected === false ) {
    $aErrors[] = 'De database is niet geselecteerd. Probeer het later opnieuw.';
  }
  else {
    //  Construeer een opdracht voor de database
    $sQuery = "SELECT   titel
               ,        bericht
               ,        DATE_FORMAT(geplaatstop,'%e-%c-%Y') AS datum
               ,        DATE_FORMAT(geplaatstop,'%H:%i') AS tijd
               FROM     nieuws
               WHERE    nieuws_id='".mysql_real_escape_string($_GET['id'])."'";
    //  Stuur de opdracht op
    $rResult = mysql_query( $sQuery, $rLink );
    //  Controleer of het gelukt is
    if ( $rResult === false ) {
      $aErrors[] = 'Er ging iets fout bij het ophalen van het nieuwsbericht.';
    }
    elseif ( mysql_num_rows($rResult) == 0 ) {
      $aErrors[] = 'Dit nieuwsbericht bestaat niet (meer)!';
    }
    else {
      $aBericht = mysql_fetch_assoc( $rResult );
    }
  }
}
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Nieuwsberichten - <?php echo $titel ?></title>
    <style type="text/css">
      p.error {
        border: 1px solid #f00;
        background: #fdd;
      }
    </style>
  </head>
  <body>
    <p>
      <a href="news_all.php">Terug naar het overzicht</a>
    </p>
    <?php
    //  Als er dingen fout zijn gegaan, vertel het
    if ( count($aErrors) > 0 ) {
      echo '<p class="error">';
      foreach ( $aErrors as $sError ) {
        print $sError . '<br />';
      }
      echo '</p>';
    }
    //  Geen fouten? Dan staat de info in $aBericht
    else {
      echo '<h2>' .
            htmlspecialchars($aBericht['titel']) .
            '</h2>';
      echo '<p><em>Geplaatst: ' .
            htmlspecialchars($aBericht['datum']) .
            ' om ' .
            htmlspecialchars($aBericht['tijd']) .
            '</em><br />' .
            htmlspecialchars($aBericht['bericht']) .
            '</p>';
    }
    ?>
  </body>
</html>

Berichten wijzigen

Als je een nieuwsbericht wilt wijzigen, kun je een scherm gebruiken wat er identiek uitziet als het invoerscherm. Je moet natuurlijk wel eerst ergens aangeven om welk nieuwsitem het gaat. Het eenvoudigste is om dit te doen vanaf een lijst met alle nieuws-items. Je zult op news_all.php dus een verwijzing moeten plaatsen naar het script waarin je die wijziging wilt verwerken (news_change.php), en daarin ook gelijk meegeven om welk id het gaat. Dat kun je als volgt doen: Het volgende stukje in news_all.php gaan we uitbreiden:

<?php
  echo '<li>';
  echo '<a href="news_read.php?id=' . urlencode( $aBericht['nieuws_id'] ) . '">';
  echo htmlspecialchars( $aBericht['titel'] );
  echo '</a>';
  echo '</li>' . PHP_EOL;
?>

geeft bijvoorbeeld als output:

 Dit is de eerste titel
 Dit is de tweede titel

Als je een bericht wilt wijzigen, kun je dat dus bij dat bericht aangeven:

<?php
  echo '<li>';
  echo '<a href="news_read.php?id=' . urlencode( $aBericht['nieuws_id'] ) . '">';
  echo htmlspecialchars( $aBericht['titel'] );
  echo '</a>';
  echo '&nbsp;&nbsp;';                                                                      // <- hier is de toevoeging
  echo '<a href="news_change.php?id=' . urlencode( $aBericht['id'] ) . '">Wijzigen</a><br />';    // <- hier is de toevoeging
  echo '</li>' . PHP_EOL;
?>

Voor de duidelijkheid heb ik er even 2 spaties (   ) tussen gezet. Het ziet er nu zo uit:

 Dit is de eerste titel  Wijzigen
 Dit is de tweede titel  Wijzigen

Netjes? Nou, niet echt. Maar dat kun je regelen in je lay-out. En er zit ook nog helemaal geen beveiliging achter. Daar kunnen we het later nog over hebben. Ik heb dus een link ( <a href="news_change.php"> ) toegevoegd die verwijst naar news_change.php. Door het meegeven van een parameter ( ?id= ) kan ik in het script news_change.php door middel van een $_GET -instructie die parameter weer 'lezen'. Die parameter heb ik hier rechtstreeks uit de tabel gehaald.

Het bestand news_change.php gaat er zo uit zien:

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
 
//  Maak een verbinding met de database. Dit plaatsen we nu vooraan in het script, want we moeten niet alleen updaten, maar ook eerst lezen.
$rLink = mysql_connect(
  'localhost',    //  host
  'root',         //  user
  ''              //  password
);
//  Controleer of het gelukt is
if ( $rLink === false ) {
  header ( 'Refresh: 5; url=news_all.php' );             // Dit toont de volgende echo gedurende 5 seconden, en gaat dan naar die URL
  echo '<ul class="errorlist">
          <li>Could not connect to database</li>
        </ul>';
  exit();
}
 
//  Selecteer je database
$bSelected = mysql_select_db( 'pfz_hwu', $rLink );
//  Controleer of het gelukt is
if ( $bSelected === false ) {
  header ('Refresh: 5; url=news_all.php' );
  echo '<ul class="errorlist">
          <li>Could not select the database</li>
        </ul>';
  exit();
}
// We hebben nu verbinding met de database 'pfz_hwu'
 
 
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
  //  Er zijn gegevens verstuurd naar deze pagina met de knop 'submit'
 
  //  We gaan de errors in een array bijhouden
  $aErrors = array();
 
  //  We hebben een niet-lege titel nodig
  if ( !isset( $_POST['titel'] ) or trim( $_POST['titel'] ) == '' ) {
    $aErrors['titel'] = 'Geef een titel voor het nieuwsbericht op!';
  }
 
  //  En uiteraard, een niet-leeg bericht
  if ( !isset( $_POST['bericht'] ) or trim( $_POST['bericht'] ) == '' ) {
    $aErrors['bericht'] = 'Voer een bericht in!';
  }
 
  if ( count($aErrors) == 0 ) {
    //  We hebben alle gegevens, en ze zijn akkoord (in ons geval: alleen maar gevuld)
 
    //  Construeer een opdracht voor de database om een record in tabel 'nieuws' te updaten
    $sUpdate = "UPDATE
                  nieuws
                SET
                  titel = '" . mysql_real_escape_string( $_POST['titel'] ) . "'
                , bericht = '" . mysql_real_escape_string( $_POST['bericht'] ) . "'
                WHERE
                  nieuws_id = '" . mysql_real_escape_string( $_POST['nieuws_id'] ) . "'";
 
    //  Stuur de opdracht op
    $rResult = mysql_query( $sUpdate, $rLink );
 
    //  Controleer of het gelukt is
    if ( $rResult === false ) {
      header( 'Refresh: 5; url=news_all.php' );
      echo '<p>Could not update news item!
            <br />Database returned: ' . mysql_error( $rLink ) . '
            <br />Query was: ' . $sUpdate . '</p>';
      exit();
		}
 
    //  Volgende pagina aub. Bijvoorbeeld de overzichtpagina.
    header('Location: news_all.php');
    exit();
  }
  // Het hierbovenstaande handelt de wijziging op een nieuws-item af. Als het gelukt is, ga je terug naar de nieuws-pagina. Als het niet
  // gelukt is, wordt een fatal-error getoond en stopt de verder verwerking.
}
else {
  // Nu weet je dat deze pagina niet door een POST is gestart. Je kunt hier dus testen of de parameter ?id in de URL is gevuld
  if ( !isset( $_GET['id'] ) OR !ctype_digit( $_GET['id'] ) ) {
    // zo niet, geef dan een foutboodschap en ga terug
    header ( 'Refresh: 5; url=news_all.php' );           //
    echo '<p>No id supplied in URL</p>';
    exit();
	}
  else {
    //  We gaan hier het gevraagde record uit de nieuws-tabel lezen
    //  Construeer een opdracht voor de database
    $sSelect = "SELECT
                  nieuws_id
                , titel
                , bericht
                FROM
                  nieuws
                WHERE
                  nieuws_id = '" . mysql_real_escape_string( $_GET['id'] ) . "'";
		//  Stuur de opdracht op
    $rResult = mysql_query( $sSelect, $rLink );
    //  Controleer of het gelukt is
    if ( $rResult === false ) {
      $sFatalError = 'Er ging iets fout bij het ophalen van het nieuwsbericht.';
    }
    elseif ( mysql_num_rows( $rResult ) == 0 ) {
      $sFatalError = 'Dit nieuwsbericht bestaat niet (meer)!';
    }
    if ( isset( $sFatalError) ) {
      header( 'Refresh: 5; url=news_all.php' );
      echo '<ul class="errorlist">
              <li>' . $sFatalError . '</li>
            </ul>';
      exit();
		}
		else {
      // als het gelukt is: zet het record in array $aBericht
      $aBericht = mysql_fetch_assoc( $rResult );
		}
	}
}
/**************************************************
*  Einde van de verwerking, begin van de uitvoer  *
**************************************************/
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Nieuwsberichten - wijzigen</title>
    <style type="text/css">
      .errorlist, .error input, .error textarea {
        border: 1px solid #f00;
        background: #fdd;
      }
      form.cmxform fieldset {
        margin-bottom: 10px;
      }
      form.cmxform legend {
        font-weight: bold;
        padding: 0 2px;
      }
      form.cmxform label {
        display: inline-block;
        line-height: 1.8;
        vertical-align: top;
      }
      form.cmxform fieldset ol {
        margin: 0;
        padding: 0;
      }
      form.cmxform fieldset li {
        list-style: none;
        margin: 0;
        padding: 5px;
      }
      form.cmxform label {
        width: 120px; /* Width of labels */
      }
    </style>
  </head>
 
  <body>
    <form action="news_change.php" method="post" class="cmxform">
      <?php
      // eerst laten we de fout(en) zien
      if ( isset($aErrors) and count($aErrors) > 0 ) {
        print '<ul class="errorlist">';
        foreach ( $aErrors as $error ) {
          print '<li>' . $error . '</li>';
        }
        print '</ul>';
      }
      ?>
      <fieldset>
        <legend>Bericht</legend>
        <ol>
          <?php
          // uit de database, dus komt het weer mee met $_POST
          // het staat wél in het formulier, maar wordt niet getoond
          echo '<input type="hidden" name="nieuws_id" value="' . htmlspecialchars( $aBericht['nieuws_id'] ) . '">';
          ?>
          <?php echo isset($aErrors['titel']) ? '<li class="error">' : '<li>' ?>
            <label for="titel">Titel</label>
            <input id="titel" name="titel" value="<?php // als er info uit $_POST komt, toon die dan, anders uit de database
            echo isset( $_POST['titel'] ) ? htmlspecialchars( $_POST['titel'] ) : htmlspecialchars( $aBericht['titel'] ) ?>" />
          </li>
          <?php echo isset( $aErrors['bericht'] ) ? '<li class="error">' : '<li>' ?>
            <label for="bericht">Bericht</label>
            <textarea id="bericht" name="bericht" cols="60" rows="10"><?php
              echo isset($_POST['bericht']) ? htmlspecialchars( $_POST['bericht'] ) : htmlspecialchars( $aBericht['bericht'] )
            ?></textarea>
          </li>
        </ol>
        <input type="submit" value="Verstuur" />
      </fieldset>
    </form>
  </body>
</html>

Berichten verwijderen

Als je een nieuwsbericht wilt verwijderen, kun je bijna dezelfde manier gebruiken als voor het wijzigen van een nieuws-item. Je zult op news_all.php dus ook een verwijzing moeten plaatsen naar het script waarin je die verwijdering wilt verwerken (news_delete.php), en daarin ook gelijk meegeven om welk id het gaat. Dat kun je als volgt doen:

Het volgende stukje in news_all.php gaan we weer uitbreiden:

<?php
    echo '<li>';
    echo '<a href="news_read.php?id='.htmlspecialchars($aBericht['nieuws_id']).'">';
    echo htmlspecialchars($aBericht['titel']);
    echo '</a>';
    echo '&nbsp;&nbsp;';                                                                      
    echo '<a href="news_change.php?id='.urlencode($aBericht['nieuws_id']).'">Wijzigen</a><br />';    
    echo '</li>' . PHP_EOL;
?>

Dit geeft bijvoorbeeld als output:

Dit is de eerste titel  Wijzigen
Dit is de tweede titel  Wijzigen

Als je een bericht wilt verwijderen, kun je dat bij het bericht aangeven:

<?php
        echo '<li>';
        echo '<a href="news_read.php?id='.htmlspecialchars($aBericht['nieuws_id']).'">';
        echo htmlspecialchars($aBericht['titel']);
        echo '</a>';
        echo '&nbsp;&nbsp;';                                                                      
        echo '<a href="news_change.php?id='.urlencode($aBericht['nieuws_id']).'">Wijzigen</a>';            // <br />  aan het eind verwijderd
        echo '&nbsp;&nbsp;';                                                                               // toegevoegd
        echo '<a href="news_delete.php?id='.urlencode($aBericht['nieuws_id']).'">Verwijderen</a><br />';   // toegevoegd
        echo '</li>' . PHP_EOL;
?>

Voor de duidelijkheid heb ik er weer even 2 spaties (   ) tussen gezet. Het ziet er nu zo uit:

Dit is de eerste titel  Wijzigen  Verwijderen
Dit is de tweede titel  Wijzigen  Verwijderen

Netjes? Nou, wederom niet echt. Maar dat kun je regelen in je lay-out (hint: in tabellen komt een kolom-inhoud netjes onder elkaar). Er is ook nog helemaal geen beveiliging geregeld. Ik heb dus een link ( <a href="news_delete.php"> ) toegevoegd die verwijst naar news_delete.php en ook weer het nieuws_id meegeeft als parameter. Je kunt in news_delete eventueel eerst nog het desbetreffende nieuws-item tonen met daaronder de vraag "Weet u zeker dat u deze wilt verwijderen? JA/NEE", maar ik heb hier gekozen voor de korte manier: direct verwijderen. Het bestand news_delete.php gaat er zo uit zien:

<?php
// zet error-reporting aan
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
 
// Voorwaarde is dat de variabele 'id' in de URL opgegeven is en gevuld is met een cijfer. Hier hoort ook een toegangscontrole thuis.
if ( isset( $_GET['id'] ) && ctype_digit( $_GET['id'] ) ){
 
//  Maak een verbinding met de database.
   $rLink = mysql_connect(
      'localhost',    //  host
      'root',         //  user
      ''              //  password
   );
//  Controleer of het gelukt is
   if ( $rLink === false ) {
      header ('refresh:5; url=news_all.php');             // Dit toont de volgende echo gedurende 5 seconden, en gaat dan naar die URL
      echo '<h2>Could not connect to database</h2>';
      exit();
   }
 
//  Selecteer je database
   $bSelected = mysql_select_db( 'pfz_hwu', $rLink );
 
//  Controleer of het gelukt is
   if ( $bSelected === false ) {
      header ('refresh:5; url=news_all.php'); 
      echo '<h2>Could not select the database</h2>';
      exit();
   }
// We hebben nu verbinding met de database 'pfz_hwu'
 
// Construeer een opdracht voor de database om een record uit tabel 'nieuws' te verwijderen
   $sDelete = "DELETE
               FROM nieuws
               WHERE nieuws_id = '" . mysql_real_escape_string( $_GET['id'] ) . "'";
 
// Stuur de opdracht op
   $rResult = mysql_query($sDelete , $rLink);
 
//  Controleer of het gelukt is
   if ( $rResult === false ) {
      header ('refresh:5; url=news_all.php'); 
      echo '<h2>Could not delete news item!</h2>';
      echo '<h2>Database returned: '.mysql_error( $rLink ).'</h2>';
      echo '<h2>Query was: </h2>'.$sDelete;
      exit();
   }
}
 
//  Volgende pagina aub. Bijvoorbeeld de overzichtpagina.
header('Location: news_all.php');
exit();
?>

En nu?

Let op dat in elk bestand nu het wachtwoord van de database staat. Het is gebruikelijk om het stukje code dat de verbinding met de database maakt, in een apart bestand te zetten. Deze kan je met include() inlezen. Wanneer je dit buiten de webroot zet, staan de gegevens weer wat verder buiten het bereik van hackers. Ook hoef je ze maar op één plek te beheren. Een heel stuk veiliger!

Het zal je hopelijk opgevallen zijn dat ondanks dat we goed beveiligen tegen SQLInjectie en XSS (respectievelijk met mysql_real_escape_string() en htmlspecialchars()). Er zit echter geen beveiliging op de toegang tot de pagina! Iedereen kan dus nu berichten maken en wijzigen, wat meestal niet is wat we willen. Je kan dit even gauw oplossen met Htaccess, maar nu de eerste stapjes met een database zijn gemaakt, kunnen we natuurlijk een veel sexier gebruikerssysteem maken. Zie hiervoor Het Wiel Uitgevonden:Inloggen!

Site Toolbox:

Persoonlijke hulpmiddelen
De laatste wijziging op deze pagina vond plaats op 17 mrt 2010 10:21. - Deze pagina werd 3.509 maal bekeken. - Disclaimers - Over PFZWIKI