Forum Moderators: coopster
I'm building an all-purpose HTML form on a single page (input.php). By default it adds a new entry, but if the url is "input.php?id=2" then it populates the form with existing data for updating record 2.
All of that works great. But when I update the values and hit the Update Record button, I get the "success" message but the fields are not updated in SQL.
My guess is that something is conflicting with the script that populates the form. I've tried to prevent this by using unique variables in the update form (e.g. $ud_id instead of $id), but to no avail.
Any help anyone can offer would be greatly appreciated!
<?php
$id = $_GET['id']; // Pulls ID value from URL if there is one, for use with third "if" statement.
if(isset($_POST['add'])) // If the "Add Record" button has been pushed, insert data into database.
{
$con = mysql_connect("localhost","*****","*****");
mysql_select_db("*****", $con);
$sql="INSERT INTO Test (title, city) VALUES ('$_POST[title]','$_POST[city]')";
if (!mysql_query($sql,$con)) die('Error: ' . mysql_error());
echo "Record successfully added to database. <a href=\"input.php\">Return to form.</a>";
mysql_close();
}
else if(isset($_POST['update'])) // If the "Update Record" button has been pushed, update database with new values.
{
$con = mysql_connect("localhost","*****","*****");
mysql_select_db("*****", $con);
$sql = "UPDATE Test SET title='$ud_title', city='$ud_city' WHERE id=$ud_id";
$result = mysql_query($sql);
echo "Record successfully updated. <a href=\"input.php\">Return to form.</a>";
}
else if($id) // If ID value provided in URL, populate update form with existing values.
{
$con = mysql_connect("localhost","*****","*****");
mysql_select_db("*****", $con);
$sql = "SELECT * FROM Test WHERE id=$id";
$result = mysql_query($sql);
$id = mysql_result($result, $i, "id");
$city = mysql_result($result, $i, "city");
$title = mysql_result($result, $i, "title");
?>
<h2>Update Form</h2>
<form method="post" action="input.php">
<input type="hidden" name="ud_id" value="<?php echo $id; ?>">
<table width="30%" border="0" cellpadding="5">
<tr>
<td>Title:</td>
<td><input type="text" name="ud_title" value="<?php echo $title; ?>"></td>
</tr>
<tr>
<td>City:</td>
<td><input type="text" name="ud_city" value="<?php echo $city; ?>"></td>
</tr>
</table>
<input type="submit" name="update" value="Update Record"></form>
<?
}
else
{
?>
<h2>Insert Form</h2>
<form method="post" action="input.php">
<table width="30%" border="0" cellpadding="5">
<tr>
<td>Title:</td>
<td><input type="text" name="title"></td>
</tr>
<tr>
<td>City:</td>
<td><input type="text" name="city"></td>
</tr>
</table>
<input type="submit" name="add" value="Add Record"></form>
<?php
}
?>
$sql = "UPDATE Test SET title='$ud_title', city='$ud_city' WHERE id=$ud_id";
Now, another glaring problem I see is in the creation of the update form itself; do you actually retrieve any data and populate the form? Notice this code:
$id = mysql_result($result, $i, "id");
$city = mysql_result($result, $i, "city");
$title = mysql_result($result, $i, "title");
Also, please be conscience of the issue of SQL injection [google.com]. Be sure to properly validate and escape your incoming data! Even the $_GET['id'] value. Anything that you intend to even come near the database needs to be properly validate and escaped. The use of a simple call to mysql_real_escape_string() [php.net] on each string you pass to the database is a start (be sure to read that page, including the examples shown). Otherwise, type casting and using parameterized queries [google.com] or stored procedures [google.com] where you can are ideal.
Furthermore, you unnecessarily repeat code. You should have a single call to the database at the top of the script; you don't need to have 3 separate calls depending on your script logic. Granted, the initial display of the empty form doesn't need a connection, but some logic could dictate that. Also, you only need a single form, you don't have to have two forms based on whether or not one of them has update data. Simply do something like this:
<input name="test" id="test" value="<?php echo ( isset($test) ) ? $test : '';?>">
The $ud_ variables come from the update form:
<input type="text" name="ud_title" value="<?php echo $title; ?>"> Or so I thought anyway. Is this not sufficient for defining $ud_title as a variable?
Excellent point on the error line - no idea why I left it out on that form. And I got this error: "Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1". I'm not seeing what this could be referring to - do you?
Yes, data is retrieved from the database and the update form is populated correctly.
Thanks for the great tips on making my code more efficient - I will definitely apply those once I get the form working. The reason for the inefficiencies is that I'm a beginner so I start out by using what I know (and what worked elsewhere). The $i comes from the script I use to view results from the database using loops - I can see that it has no use here, though.
As for security, the form is a tool for only me to update the database - I've learned a bit about SQL injection and it has me paranoid enough to not make a public form until I'm sure I've made it secure. Your links will be very helpful towards achieving that.
Thanks again - and I hope you or someone else can shed some light on the problem! I still can't figure out what's going wrong with the update form. Evidently the problem is that it doesn't "see" the $ud_title type variables, but I don't know why.
To test this, at the top of your script add this single line:
print_r($_POST);
Once you see what's going on, you should realize that you need to access the $_POST superglobal array. Add these lines prior to the UPDATE statement, e.g.
// run each POST element through this loop
foreach ($_POST AS $k => $v) {
// ..trim, slash, escape... explained below...
$$k= mysql_real_escape_string( stripslashes( trim( $v ) ) );
}
// and then your original update
$sql = "UPDATE Test SET title='$ud_title', city='$ud_city' WHERE id=$ud_id";
What those couple of lines do is, they take the $_POST data, trim any extraneous spaces off the end of it, strip off any slashes added by the dread magic quotes [php.net], and then run mysql_real_escape_string() on it. Then the entire result of that is reassigned to a variable variable with the name of the actual POST field. In other words, $_POST['ud_title'] becomes the local variable $ud_title, etc. This isn't the most efficient code, but it's good in a pinch. Good luck!