Book: PHP MYSql Novice to Ninja - Delete Joke - Always deletes the last joke

Hi,

I’m currently working on Chapter four of Kevin Yanks - PHP/MYSQL Novice to Ninja 5th Edition. Im stuck in the Delete Jokes portion (Starts with page 130). And it seems i ran into a bug/feature?.

I am able to add jokes fine. but when I click on the delete button of a particular joke, the script always deletes the last Joke in the database instead the one i clicked on the delete button on.

I have tried downloading the sample source code from the website and i get the same results. I’m really bothered with this since i really want to get the script working as intended.

Here is my index.php:

<?php
if (get_magic_quotes_gpc())
{
	$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
	while (list($key, $val) = each($process))
	{
		foreach ($val as $k => $v)
		{
			unset($process[$key][$k]);
			if (is_array($v))
			{
				$process[$key][stripslashes($k)] = $v;
				$process[] = &$process[$key][stripslashes($k)];
			}
			else
			{
				$process[$key][stripslashes($k)] = stripslashes($v);
			}
		}
	}
	unset($process);
}

if (isset($_GET['addjoke']))
{
	include 'form.html.php';
	exit();
}

try
{
	$pdo = new PDO('mysql:host=localhost;dbname=ijdb', 'root', 'root');
	$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	$pdo -> exec('SET NAMES "utf8"');
}
catch (PDOException $e)
{
	$error = 'Unable to connect to the database server.';
	include 'error.html.php';
	exit();
}

if (isset($_POST['joketext']))
{
	try
	{
		$sql = 'INSERT INTO joke SET
			joketext = :joketext,
			jokedate = CURDATE()';
		$s = $pdo->prepare($sql);
		$s->bindValue(':joketext', $_POST['joketext']);
		$s->execute();
	}
	catch (PDOException $e)
	{
		$error = 'Error adding submitted joke: ' . $e->getMessage();
		include 'error.html.php';
		exit();
	}
	
	header('Location: . ');
	exit();
}

if (isset($_GET['deletejoke']))
{
	try
	{
		$sql = 'DELETE FROM joke WHERE id = :id';
		$s = $pdo->prepare($sql);
		$s->bindValue(':id', $_POST['id']);
		$s->execute();
		
	}
	catch (PDOException $e)
	{
		$error = 'Error deleting joke: ' . $e->getMessage();
		include 'error.html.php';
		exit();
	}
	
	header('Location: .');
	exit();
}

try
{
	$sql = 'SELECT id, joketext FROM joke';
	$result = $pdo->query($sql);

}
catch (PDOException $e)
{
	$error = 'Error fetching jokes: ' . $e->getMessage();
	include 'error.html.php';
	exit();
}

while ($row = $result->fetch())
{
	$jokes[] = array('id' => $row['id'], 'text' => $row['joketext']);
}

include 'jokes.html.php';
?>

and my jokes.html.php

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>List of Jokes</title>
	</head>
	<body>
		<p><a href="?addjoke">Add your own joke</a></p>
		<p>Here are all the jokes in the database:</p>
		<?php foreach ($jokes as $joke): ?>
			<form action="?deletejoke" method="post">
				<blockquote>
					<p>
						<?php echo htmlspecialchars($joke['text'], ENT_QUOTES, 'UTF-8'); ?>
						<input type="hidden" name="id" value="<?php echo $joke['id']; ?>">
						<input type="submit" value="delete">
					</p>
				</blockquote>
				<?php endforeach; ?>
			</form>
	</body>
</html>

Hope someone can point me to the right direction.

Guess something’s wrong with the joke ID. Let’s figure it out.

if (isset($_GET['deletejoke']))
{
	try
	{
		$sql = 'DELETE FROM joke WHERE id = :id';
		$s = $pdo->prepare($sql);
		$s->bindValue(':id', $_POST['id']);
		$s->execute();
		
	}
	catch (PDOException $e)
	{
		$error = 'Error deleting joke: ' . $e->getMessage();
		include 'error.html.php';
		exit();
	}
	
	header('Location: .');
	exit();
}

Replace the above code with the following.

if(isset($_GET['deletejoke'])) {
    echo $_POST['id'];
}

Now, try deleting some jokes. Are you getting the same output each time you delete a joke?

You are getting that kind of behavior because your <?php endforeach; ?> is before your closing </form> tag. It needs to be after the closing </form> tag.

This got it right! thanks cpradio!