[ATTACH]5041[/ATTACH]

The code works when I run it at my website.
The page with the guestbook can be namned anything. I use guestbook.php.
What I am not so sure about is the submission from the textarea.
I run trim, htmlspecialchars and nl2br on it BEFORE I insert into db.

The database file should be protected by this in .htaccess:

<Files guestbook.db>
Require all denied
</Files>
<?php

// Connect to a Sqlite database file.
// If table not exists then create table.
$dbh = new PDO("sqlite:guestbook.db");
$sth = $dbh->prepare(
"CREATE TABLE IF NOT EXISTS entries (
	id INTEGER PRIMARY KEY,
	comment TEXT,
	author TEXT,
	email TEXT,
	time INTEGER)");
$sth->execute();

// If entry is submit and not empty then insert into db.
// If so then set a cookie 'posted'. Cookie expires after 1 hour.
if(isset($_POST['entry'])){
	$name  = trim($_POST['name']);
	$email = trim($_POST['email']);
	$msg   = trim($_POST['entry']);
	$msg   = htmlspecialchars($msg,ENT_NOQUOTES);
	$msg   = nl2br($msg);
	if(!empty($name) && !empty($email) && !empty($msg)){
		$time  = time();
		$sth = $dbh->prepare(
			"INSERT INTO entries (comment,author,email,time)
			 VALUES ( ?,?,?,? )");
		$sth->execute(array($msg,$name,$email,$time));
		$dbh = $sth = null;
		setcookie("posted", true, time()+3600);  /* expire in 1 hour */
		header("location:".$_SERVER['PHP_SELF']);
		exit();
	}
}

// Start page output.
// If cookie 'posted' is not set then display form for submit.
echo '<html><body style="background:#386087">
<div style="padding-left:200px">'."\n";
echo "<b>&nbsp;GUESTBOOK</b>\n";
if(!isset($_COOKIE['posted'])){
?>
<div style="width:300px">
	<form style="margin:0px" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
  		<fieldset style="background:#99ccee">
    	Name: <input type="text" size="30" name="name"><br>
    	Email: <input type="text" size="30" name="email"><br>
		Message: 
		<textarea rows="4" cols="50" name="entry"></textarea>
		<input type="submit" value="SUBMIT">
  		</fieldset>
	</form>
</div>	
<?php
}

// Get the last 20 posts and display them descending.
// The latest post on top.
$sth = $dbh->prepare("SELECT * FROM entries
	                  ORDER BY id DESC LIMIT 20");
$sth->execute();
foreach ($sth->fetchAll(PDO::FETCH_OBJ) as $row) {
    echo '<fieldset style="width:427px;background:#99ccee">'."\n";
    echo $row->author.'<span style="padding-left:16px">'."\n";
    echo '<a href="mailto:'.$row->email.'" target="_blank">Send mail</a>'."</span>\n";
    echo '<span style="float:right">'.date("Y-m-d H:i",$row->time)."</span>\n";
    echo '<fieldset style="background:#aaeeff">'."\n";
    echo $row->comment."\n";
    echo "</fieldset></fieldset>\n\n";
}
$dbh = $sth = null;
echo "</div></body></html>";

?>
guestbook1.png

    As a rule of thumb it is much better to store the content in the database as-is (obviously prepared/escaped properly to avoid injection) and to only sanitize it when displaying it, otherwise you run the risk of mangling user input.

    It's kind of neat that you have the table creation in your script, but it's going to be unnecessary 99.999% of the time. I wouldn't bother with it.

    I don't know if it's important to you or not, but you're not doing any validation on the email address. You could easily check if it's valid by using the [man]filter_var/man function and using the FILTER_VALIDATE_EMAIL flag. This would also prevent it from being empty.

    Maybe I am missing something but I am confused as to why you need a cookie at all and why you're redirecting back to the same page.

    You don't have any kind of doctype or character encoding. I would definitely include those.

      Write a Reply...