Kirjoittaja: Metabolix
Kirjoitettu: 28.05.2012 – 12.06.2012
Tagit: ohjelmointitavat, tietoturva, koodi näytille, vinkki, web
Vieraskirjan viestit tallennetaan usein tietokantaan, kuten PHP-oppaassa. Jotkut aloittelijat käyttävät ilmaista sivutilaa, jossa tietokantaa ei ole. Silloin täytyy turvautua tiedostoihin.
Aloittelijan ei yleensä kannata miettiä nopeutta: esimerkiksi sata viestiä vieraskirjassa on tietokoneelle pieni määrä. Niinpä alkuun voi huoletta lukea kaikki viestit kerralla muistiin ja myös tallentaa ne kaikki uudestaan aina, kun viestejä tulee lisää.
Tiedostoja voi lukea ja kirjoittaa funktioilla file_get_contents ja file_put_contents, ja muuttujia saa tekstiksi ja takaisin funktioilla serialize ja unserialize. Valmiita funktioita käyttämällä säästää aikaa ja vaivaa, ja lisäksi nämä funktiot toimivat varmasti oikein, toisin kuin monet omatekoiset tiedostoviritelmät.
<?php // Yritetään laittaa virheilmoitukset käyttöön. @ini_set("display_errors", 1); @ini_set("error_reporting", E_ALL); // Lähetetään UTF-8-merkistöilmoitus. Koodi pitää myös tallentaa UTF-8-muodossa. header("Content-Type: text/html; charset=UTF-8"); // Jos viestitiedosto puuttuu, luodaan se. if (!file_exists("viestit.txt")) { // Tallennetaan tiedostoon array() eli tyhjä taulukko tekstiksi muutettuna. if (!file_put_contents("viestit.txt", serialize(array()), LOCK_EX)) { trigger_error("Tiedoston luonti ei onnistu!", E_USER_ERROR); } } // Ladataan viestit. $viestit = unserialize(file_get_contents("viestit.txt")); // Jos lomake on lähetetty... if (isset($_POST["nimimerkki"], $_POST["teksti"])) { // ... lisätään viesti. end($viestit); $id = key($viestit) + 1; $viestit[$id] = array( "nimimerkki" => $_POST["nimimerkki"], "teksti" => $_POST["teksti"], ); // Tallennetaan tiedot. if (!file_put_contents("viestit.txt", serialize($viestit), LOCK_EX)) { trigger_error("Tallennus ei onnistu!", E_USER_ERROR); } // Ohjataan käyttäjä katsomaan omaa viestiään. // Jos lähetettiin viesti, suoritus päättyy tähän. $sivu = "http://{$_SERVER["HTTP_HOST"]}{$_SERVER["SCRIPT_NAME"]}"; header("Location: {$sivu}#viesti_{$id}"); die("OK!"); } // Näytetään sivu. ?> <!DOCTYPE html> <head> <meta charset="UTF-8" /> <title>Vieraskirja</title> </head> <body> <h1>Vieraskirja</h1> <h2>Viestit</h2> <dl> <?php // Tulostetaan viestit. foreach ($viestit as $id => $viesti) { // Tekstin tulostuksessa htmlspecialchars on tärkeä. // nl2br tekee rivinvaihdoista HTML:n <br>-tageja. $html_nimi = htmlspecialchars($viesti["nimimerkki"]); $html_viesti = nl2br(htmlspecialchars($viesti["teksti"])); // Laitetaan elementille id linkkejä (#viesti_123) varten. echo "<dt id='viesti_{$id}'>#{$id}: {$html_nimi}</dt>"; echo "<dd>{$html_viesti}</dd>"; } ?> </dl> <h2>Lomake</h2> <?php // Pelkkä "?" lomakkeen toimintona johtaa samaan skriptiin. ?> <form action="?" method="POST"> <dl> <dt>Nimimerkki</dt> <dd><input name="nimimerkki" type="text" /></dd> <dt>Viesti</dt> <dd><textarea name="teksti" rows="5" cols="60"></textarea></dd> </dl> <button type="submit">Lähetä</button> </form>
Siitä on vuosi jos ei useampikin (eli useampi), kun olen kirjoittanut viimeksi riviäkään PHP:tä. Silmääni osui vinkkiä vilkaistessa kuitenkin tuo taulukon kasvattaminen, sillä tuollehan on PHP:ssa muistaakseni oma lyhytmuotonsakin.
Onko tällä lyhytmuodolla jotain ratkaisevia puutteita (epäintuitiivisehkon syntaksin lisäksi), vai onko tämä vaihtoehtoinen tapa käytössä ennemminkin vain akateemisista syistä?
eq: Viestin lisäyksen jälkeen siirrytään avaimen avulla suoraan kyseiseen viestiin, joten avain täytyy kuitenkin jossain vaiheessa hakea. Minusta on selvempää hakea avain jo aluksi, jotta on helppo nähdä, että $id on sama viestin lisäyksessä ja ohjauksessa. Tietokannan kanssa toki toimittaisiin juuri päinvastoin.
Miten tuon saa toimimaan ilman numerointia?
TVdata, tietenkin voit poistaa #-osan osoitteesta ja numeron HTML-koodista, jos et halua niitä.
Entä miten viesteihin saisi rivinvaihdon?
Painamalla enteriä tekstikentässä.
Tarkoitin kyllä automaattista rivinvaihtoa.
Rivit katkeavat tarvittaessa aina automaattisesti, jos et itse muuta määrää.