Kirjautuminen

Haku

Tehtävät

Koodit: HTML, PHP: Vieraskirja tiedostoilla

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>

Kommentit

eq [11.06.2012 09:55:47]

#

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ä?

Metabolix [12.06.2012 22:58:28]

#

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.

TVdata [15.09.2012 15:26:42]

#

Miten tuon saa toimimaan ilman numerointia?

Metabolix [15.09.2012 16:56:32]

#

TVdata, tietenkin voit poistaa #-osan osoitteesta ja numeron HTML-koodista, jos et halua niitä.

TVdata [22.09.2012 18:13:18]

#

Entä miten viesteihin saisi rivinvaihdon?

Metabolix [23.09.2012 12:38:09]

#

Painamalla enteriä tekstikentässä.

TVdata [26.09.2012 18:59:29]

#

Tarkoitin kyllä automaattista rivinvaihtoa.

Metabolix [26.09.2012 19:03:18]

#

Rivit katkeavat tarvittaessa aina automaattisesti, jos et itse muuta määrää.

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta