Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Foorumi ei tulosta viestejä

Hengilö [19.06.2013 13:22:47]

#

Yritin tehdä jonkinlaisen foorumin tämän vinkin avulla. Lisäsin siihen topicit, mutta sen jälkeen viestit eivät enää tulostuneet ruudulle. Koodi:

<?php

try {
	session_start();
	if(!isset($_SESSION["id"])) {
		header("Location: signin.php?returnurl={$_SERVER["PHP_SELF"]}");
		die();
	} else if(isset($_SESSION["aika"])) {
		if($_SESSION["aika"] + 1800 < time()) {
			header("Location: signin.php?returnurl={$_SERVER["PHP_SELF"]}");
			die();
		}
	}
	$_SESSION["aika"] = time();

	class foorumi {
		private $topicit;

		public function __construct() {
			$this->topicit = file("topicit.txt");
		}

		public function etusivu() {
			?>
			<p>Valitse selattava topic alta.</p>
			<table>
			<?php
			foreach($this->topicit as $topic) {
				$tiedot = explode("|", $topic);
				echo "<tr><td><a href=\"testforum.php?tapahtuma=lue&t={$tiedot[0]}\">{$tiedot[1]}</a></td></tr>";
			}
			echo "</dl>";
		}

		public function hae() {
			if (!file_exists("viestit.txt")) {
				if (!file_put_contents("viestit.txt", serialize(array()), LOCK_EX)) {
					trigger_error("Tiedoston luonti ei onnistu!", E_USER_ERROR);
				}
			}
			$viestit = unserialize(file_get_contents("viestit.txt"));
			return $viestit;
		}

		public function lue($viestit, $topicid) {
			?>
			<p><a href="testforum.php?tapahtuma=lomake&t=<?php echo $topicid ?>">Uusi viesti</a></p>
			<?php
			if(!empty($viestit)) {
				foreach ($viestit as $id => $viesti) {
					if($viesti["topicid"] == $topicid) {
						$nimi = htmlspecialchars($viesti["nimi"]);
						$aika = htmlspecialchars($viesti["aika"]);
						$viesti = nl2br(htmlspecialchars($viesti["teksti"]));
						echo "<p><a name='{$id}'><small>#{$id}:</small></a><br />{$nimi}";
						echo " (" . date("d.m.Y H:i", $aika) . "):<br />";
						echo "{$viesti}</p><hr />";
					}
				}
			} else {
				echo "<p>Tässä topicissa ei ole viestejä!</p>";
			}
		?>
		<p><a href="#up">Takaisin ylös</a></p>
		<?php
		}

		public function laheta($nimi, $topicid, $teksti) {
			$viestit = $this->hae($topicid);
			end($viestit);
			$id = key($viestit) + 1;
			$viestit[$id] = array(
				"nimi" => $nimi,
				"aika" => time(),
				"topicid" => $topicid,
				"teksti" => $teksti,
			);
			if (!file_put_contents("viestit.txt", serialize($viestit), LOCK_EX|FILE_APPEND)) {
				trigger_error("Tallennus ei onnistu!", E_USER_ERROR);
			}
			$sivu = "testforum.php?tapahtuma=lue&t={$topicid}";
			header("Location: {$sivu}#{$id}");
			die();
		}

		public function lomake($topicid) {
			$kayttajat = file("kayttajat.txt");
			foreach($kayttajat as $kayttaja) {
				$tiedot = explode("|", $kayttaja);
				if($tiedot[0] == $_SESSION["id"]) {
					$nimi = $tiedot[1];
					break;
				}
			}
			?>
			<form action="?tapahtuma=laheta" method="post">
			<input type="hidden" name="nimi" value="<?php echo $nimi ?>" />
			<p>Viestisi: <br /><textarea name="teksti" rows="15" cols="60"></textarea></p>
			<input type="hidden" name="topicid" value="<?php echo $topicid ?>" />
			<button type="submit">Lähetä</button>
			</form>
			<?php
		}
	}

	$foorumi = new foorumi();

	include("yla.php");

	if(isset($_GET["tapahtuma"])) {
		$tapahtuma = $_GET["tapahtuma"];
	} else {
		$tapahtuma = "etusivu";
	}

	if($tapahtuma == "etusivu") {
		$foorumi->etusivu();
	} else if($tapahtuma == "lue") {
		$foorumi->lue($foorumi->hae(), $_GET["t"]);
	} else if($tapahtuma == "lomake") {
		$foorumi->lomake($_GET["t"]);
	} else if($tapahtuma == "laheta") {
		$foorumi->laheta($_POST["nimi"], $_POST["topicid"], $_POST["teksti"]);
	} else {
		throw new Exception("Tuntematon tapahtuma: " . $tapahtuma . "!");
	}
	include("ala.php");
} catch(Exception $p) {
	die("Poikkeus: " . $p->getMessage());
}

?>

Käyttäjä on aiemmin jo kirjautunut sivulle.
Kayttajat.txt on muotoa:

viesti-id|nimi|salasana(kryptattu)

Ja topicit.txt:

topicid|topicin nimi

Tietääkö joku, mitä tehdä?

Metabolix [19.06.2013 13:38:28]

#

Olet lisännyt omin päin tiedoston kirjoitukseen valitsimen FILE_APPEND. Ota se pois. Koodivinkissä tiedosto luetaan aina kokonaan ja tallennetaan aina kokonaan. Kun lisäät ylimääräistä dataa tiedoston loppuun, datan purkaminen (unserialize) ei enää onnistu. Jos lukisit virheilmoituksia, varmaan tietäisit tämänkin jo. Pidä aina kaikki virheilmoitukset näkyvissä, kun koodaat.

Lisäksi koodisi on pullollaan muita pieniä virheitä ja tietoturva-aukkoja. Laita virheilmoitukset ja varoitukset näkyviin, korjaa lukuisat XSS-aukot ja validoi sivujen HTML-koodi.

Hengilö [19.06.2013 13:44:00]

#

No nytpä näyttää toimivan.

Edit: Ei muuten tule edes noita Notice-tason ilmoituksia...

reino [19.06.2013 15:20:58]

#

Jos virheviestit eivät tulostu niin voit koittaa laittaa koodin alkuun funktion error_reporting. Se määrittää mitkä virheet näytetään.

Esimerkki:

// Näytä kaikki virheet
error_reporting(E_ALL);

// Älä näytä virheitä
// (Suositeltavaa julkisilla sivuilla)
error_reporting(0);

Lue lisää PHP:n manuaalista.

The Alchemist [19.06.2013 16:15:23]

#

Virheraportointi on kyllä hyvä pitää päällä tuotannossakin (ns. julkiset sivut), koska muutoinhan virheiden syy ja kriittisyys voi olla hyvin vaikeaa selvittää jälkikäteen. On eri asia kieltää virheiden tulostaminen käyttäjälle kuin ottaa virheraportointi pois päältä. Virheiden julkinen tulostus estetään asetuksella display_errors = 0.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta