Need some help with CH4 from PHP & MySQL: Novice to Ninja

I’ve been going through this book and I’ve been trying to apply the lessons to a mock project just to try to solidify the concepts in my mind. I basically finished the lessons in CH4 of the book and I’m applying what I learned to a new database. This chapter is about displaying, adding and deleting content to a database using PDO’s to connect to the db and submit queries.

I can get the book lessons to work but I can’t seem to get my own project to work. The only part that doesn’t seem to work is the INSERT query. What works is I’m able to display the contents of the database, however when I submit new content it is not added to the database.

Here is the link I’m working with just so you can see what I mean:
http://www.lostdoggrafix.com/tuts/php/php-nov2ninja/games/
(its just an unformatted page, I just want to get the functionality going first and foremost)

I’m stuck and would appreciate a second set of more experienced eyes to look over what I have and maybe point me in the right direction. I’m sure its some stupid mistake but I’m still a novice at PHP so I’m having trouble locating it.

Thanks in advance for any help :]

Below is my code:

My database table:

CREATE TABLE IF NOT EXISTS `PCgames` (
  `game_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'stores the primary key',
  `title` varchar(75) COLLATE utf8_unicode_ci NOT NULL COMMENT 'stores the game title',
  `type` varchar(10) COLLATE utf8_unicode_ci NOT NULL COMMENT 'stores the game type',
  PRIMARY KEY (`game_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;

This is the controller script: index.php

<?php
//disable magic quotes at runtime
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 the '?addjoke' link is clicked (from the 'games.html.php' template)
then display the 'addgame.html.php' template. */
////////////////////////////////////////////////////////////////////////
if (isset($_GET['addgame'])) {
	include 'addgame.html.php';
	exit();
}

//connect to database
try
{
  $pdo = new PDO('mysql:host=******;dbname=*****', '*****', '******');
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $pdo->exec('SET NAMES "utf8"');
}
catch (PDOException $e) //catch any error messages
{
  $error = 'unable to connect to database' . $e->getMessage();
  include ('error.html.php');
  exit();
}
/*$output = "Connection successfully attained!";
include ('connected.html.php');*/

////////////////////////////////////////////////////////
/*Check to see if the addjoke form has been submitted*/
///////////////////////////////////////////////////////
if (isset($_GET['title']) && isset($_GET['type'])) {
	
	try
	{
	//create SQL Prepared Statemnt to insert form data to the database
	//this is done to protect against SQL injection attacks
	$sql = 'INSERT INTO PCgames SET
	title = :title,
	type = :type';
	$s = $pdo->prepare($sql);
	$s->bindValue(':title', $_POST['title']);
	$s->bindValue(':type', $_POST['type']);
	$s->execute();
	}
	catch(PDOException $e)
	{
		$error = 'Error adding game to database ' . $e->getMessage();
		include 'error.html.php';
	}
	header('location: .');
	exit();
}

//create query to select the contents of the database
try
{
	$sql = 'SELECT * FROM PCgames';
	$results = $pdo->query($sql);
}
catch (PDOException $e)
{
	$error = 'Unable to fetch data: ' . $e->getMessage();
	include 'error.html.php';
	exit();
}

//fetch the results of the database
while($row = $results->fetch()) {
	$games[] = array( 'title'=> $row['title'], 'type'=> $row['type']);
}
include 'games.html.php';


?>

games.html.php template:

<body>
<h1>My Games</h1>
<p><a href="?addgame">Add a new Game</a></p>
<?php
foreach($games as $game) { ?>
<p>
	<?php
	echo htmlspecialchars($game['game_id'], ENT_QUOTES, 'UTF-8');
	echo htmlspecialchars($game['title'], ENT_QUOTES, 'UTF-8');
	echo htmlspecialchars($game['type'], ENT_QUOTES, 'UTF-8');
	?>
</p>
<?php
}
?>
</body>

addgame.html.php

<body>
<form action="?" method="post">
<p>Add Game Title:<br />
<input type="text" id="title" name="title" /><br />
Add Game Type:<br />
<input type="text" id="type" name="type" /></p>
<p><input type="submit" id="submit" name="submit" value="Add a new Game!" /></p>


</form>
</body>

Code to update a record


UPDATE PCgames SET
	title = :title,
	type = :type
WHERE game_id =12

vs code to add a new row where the id is an autoincrement


INSERT INTO PCgames (title, type)
VALUES (:title, :type);

I think that’s your problem.

Thanks for your response Cups,

I tried adding your suggested query where the game_id is auto-incremented and I get the same problem, for some reason the submitted form data isn’t going to the database

Ok, so now you need to start dividing and conquering.

Is your form correctly submitting to the form handler? Prove it.


////////////////////////////////////////////////////////
/*Check to see if the addjoke form has been submitted*/
///////////////////////////////////////////////////////
if (isset($_GET['title']) && isset($_GET['type'])) {
 
	try 
	{
	//create SQL Prepared Statemnt to insert form data to the database
	//this is done to protect against SQL injection attacks
	$sql = 'INSERT INTO PCgames (title, type) values(:title ,:type)';
	$s = $pdo->prepare($sql);
	$s->bindValue(':title', $_POST['title']);
	$s->bindValue(':type', $_POST['type']);
	$s->execute();
	}
	catch(PDOException $e)
	{
		$error = 'Error adding game to database ' . $e->getMessage();
		include 'error.html.php';
	}

// for now stop the relocate, just echo some variables onto the screen
// as a means of debug
// comment these lines out as needed, and remove them b4 going live

echo 'Well at least we got to the addgame handler ...';
echo $sql
var_dump($_POST);


	//header('location: .');
	exit();
}

My apologies for not responding sooner, I’ve been pressed for time the last week or so.

OK, what happens when I comment out the “header(‘location: .’)” statement and try to echo the $sql and post data on the controller script, however my page just goes back to displaying the games.html.php template.

I’ve also tried adding your code…

echo 'Well at least we got to the addgame handler ...';
echo $sql
var_dump($_POST);

…to a template called submitted.html.php and including it, in place of echoing it directly on the controller script but I get the same result.

I may just abandon this and start from scratch, this was mostly meant as just an exercise for me get the concepts down. I’ve spent too much time banging my head against the wall on this,lol.

I am sorry, I am not familiar with this book.

re banging your head against a wall.

When this happens, take some time out. Recreate the problem in miniature, you are only learning after all.

Keep your html form as is for now.

Change the target of the form to test.php or something obvious.

<form action=“test.php” method=“GET”>

Don’t do any magical header/location stuff, just echo onto the screen pseudocode stating what should happen.

You really need to nail how GET strings are being handled by the post back form handler (test.php in this case).


<?php
if (isset($_GET) ){
var_dump($_GET);
echo '<hr />';
}

// now do single line debugs of each of your expected outcomes.

if(isset($_GET['addgame'])){ // a conditional check

echo 'OK, Now I am adding a book';
echo 'OK, Now I am going to relocate to confirm.php'; // or whatever
exit();
}

// and so on

GET is sometimes easier to grok because you get to see the variables in the address bar.

Then add more conditionals, make sure it all works.

Then change all the references to POST a) in your form and b) in your post back handler

Then start adding code back in to your test.php

Then when everything works, put that back where it was before - and hopefully at some point in that journey you will have:

both fixed and broken things
learned something
moved on from your brick wall
learned how to learn by telling PHP to PROVE what we are only ASSUMING

We’ve all done the same thing one way or another.

Thanks a lot for your response Cups. I appreciate the suggestions and quick tutorial on bug hunting! I really like working with PHP but I know I have a long way to go so I appreciate the suggested methodology for tracking down bugs. I’ll keep at it.