I am getting an error when trying to insert some values into a MySQL Database - My page currently reads the value 'EventID' which is passed through the URL and allows me to Add Results based on that EventID. I currently have a Drop down box which is populated by the Members within the members table.
I get this horrid error:
Cannot add or update a child row: a foreign key constraint fails (clubresults.results, CONSTRAINT ResultEvent FOREIGN KEY (EventID) REFERENCES events (EventID) ON DELETE CASCADE)
I am not able to change the table structure so any help would be great appreciated.
Note - I'm currently having it echo the SQL to find the error as to why it won't insert.
<?php
error_reporting (E_ALL ^ E_NOTICE);
$con = mysql_connect("localhost","root","");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("clubresults", $con);
// Get id from URL
$id = mysql_real_escape_string($_GET['EventID']);
// If id is number
if ($id > 0)
{
// Get record from database
$sql = "
SELECT EventID
FROM results
WHERE EventID = " . $id;
$result = mysql_query($sql);
}
if (isset($_POST['submit'])) {
$sql="INSERT INTO results (MemberID, Score, Place)
VALUES
('".$_POST['student']."', '".$_POST['Score']."', '".$_POST['Place']."')";
$add_event = mysql_query($sql) or die(mysql_error());;
echo $add_event;
}
HTML Form -
$_SERVER['PHP_SELF']?>" method="post">
<table border="0"><p>
<tr><td colspan=2></td></tr>
<tr><td>Member Name: </td><td>
<?php
$query="SELECT * FROM members";
/* You can add order by clause to the sql statement if the names are to be displayed in alphabetical order */
$result = mysql_query ($query);
echo "<select name=student value=''>Student Name</option>";
// printing the list box select command
while($nt=mysql_fetch_array($result)){//Array or records stored in $nt
echo "<option value='$nt[MemberID]'>$nt[Firstname] $nt[Surname]</option>";
/* Option values are added by looping through the array */
}
echo "</select>";// Closing of list box
?>
<tr><td>Score:</td><td>
<input type="text" name="Score" maxlength="10">
<tr><td>Place:</td><td>
<input type="text" name="Place" maxlength="10">
</td></tr>
<tr><th colspan=2><input type="submit" name="submit"
value="Add Result"> </th></tr> </table>
</form>
You have to insert the EventID into your results record:
$sql="INSERT INTO results (MemberID, Score, Place, EventID) VALUES (?, ?, ?, ?)";
Note I have used ? placeholders in place of your $_POST variables (which left you vulnerable to SQL injection).
You should use instead prepared statements into which you pass your variables as parameters that do not get evaluated for SQL, but they are not available in the ancient MySQL extension that you're using (which the community has begun deprecating anyway, so you really should stop writing new code with it); use instead either the improved MySQLi extension or the PDO abstraction layer.
Related
I have a PHP PDO statement that queries a table in my database to return a list of users.
The form is used to log maintenance events, so the username is used to log the person that has done the maintenance.
However when the form is submitted - its submitting the value of the dropdown box instead of the ID of the row it's returning. The table its submitting it into has a column "engineer" the is referencing the engineers table e.g. John Doe id = 1.
I think I need it to post the ID and not the name.. Here's my code:
<form action="" method="post">
<label>Engineer Name:</label>
<br/><br/>
<select id="teamlist" name="teamlist">
<?php
$pdo = new PDO('mysql:host=localhost;dbname=frontier_maintlog', 'user', 'pass');
#Set Error Mode to ERRMODE_EXCEPTION.
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('Select name from engineers');
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo '<option>'.$row['name'].'</option>';
}
?>
</select>
<br/><br/>
<input type="submit" value=" Submit " name="submit"/><br />
</form>
and here's the bit that does the inserting into database:
$sql = "INSERT INTO log (engineer, description, fa_description)
VALUES ('".$_POST["engineer"]."','".$_POST["description"]."','".$_POST["fa_description"]."')";
The "log" table looks a bit like this:logtableimage
Thank you! Sorry if it doesn't make perfect sense.
Here's the error I receive SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'engineer' at row 1
Error is that you are inserting string to int datatype.
You should also select id value from engineers table, to use for options:
...
$stmt = $pdo->prepare('Select id,name from engineers');
$stmt->execute();
// and assign value to options
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo "<option value='$row[id]'>$row[name]</option>";
}
You have to assign a value to option. Every option needs to have it's own value. In you case you just echo the option.
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo '<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
I am trying to enter the data that I get from the two variables stuname and book in the table's username and book columns !! I only want to enter data into those two columns since the id column is auto increment and the date is auto updated with time stamp!!! Each time I run my code I enter my data into the two text fields and when I press submit I get this message!!
Warning: mysqli_select_db() expects exactly 2 parameters, 1 given in C:\xampp\htdocs\assignment.php on line 35
Warning: mysqli_query() expects parameter 1 to be mysqli, string given in C:\xampp\htdocs\assignment.php on line 36
Here is my Code:
<?php
$servername = "localhost";
$Username = "root";
$Password = "admin";
$Dbname = "nfc";
$conn = mysqli_connect($servername, $Username, $Password, $Dbname);
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
echo "Connected successfully";
if(isset($_POST["stuname"])&&($_POST["book"]))
{
$stuname = $_POST["stuname"];
$book =$_POST["bookname"];
$sql = "INSERT INTO library (id, username, book, date)
VALUES ('', '$stuname', '$book','')";
mysqli_select_db($conn, 'nfc') or die(mysqli_error($con));
$retval = mysqli_query( $sql, $conn );
if(! $retval )
{
die('Could not enter data: ' . mysql_error());
}
else
{
echo "Success";
}
echo " to stuname ". $stuname;
echo " to book ". $book;
}
?>
<form id="form1" name="form1" method="post" action="#">
<p>
<label for="1">student name</label>
<input type="text" name="stuname" id="1" />
</p>
<p>
<label for="12">book name</label>
<input type="text" name="bookname" id="12" />
</p>
<input name="submit" type="submit" value="Submit" />
</form>
In the mysqli_query you should put the conn first and then the query itself
$retval = mysqli_query( $conn, $sql );
The first problem was solved by #Ghost in the comments.
Now on to the rest of the problems:
1. Your database design is faulty
This should have failed immediately because you are inserting an empty value for id. id should be a primary key and therefore should be unique. An auto-increment doesn't work if you insert an empty value.
2. Your insert statement is faulty
You should exclude an auto-increment column in the INSERT statement and should not use an empty value for date. If date is a timestamp, you should either use NULL if the time is supposed to be empty or use NOW() to use the current timestamp.
3. You shouldn't be using insert on this page according to your comments.
You should be using UPDATE or REPLACE instead of INSERT if you are trying to update the existing row but you should be using the primary key to signify which row you are replacing. Right now, it looks like you don't have a primary key, so refer to my 1st point.
4. Security concerns: Your query is subject to SQL injections.
You use user input ($_POST) directly in a query. Any malicious user can take advantage of this and extract, delete, or manipulate data in your database. You should be using prepared statements, or at the very least escape functions.
I have two tables, users and comments. I need to add firstname and lastname to users and the comments to the comments table with the user id as a foreign key in comments. I am using phpmyadmin to do the add the foreign key constrain and relationships.
This is my html form:
<form action="dbconnect.php" method="post">
Firstname: <input type="text" name="firstname"><br />
Lastname: <input type="text" name="lastname"><br />
Comments: <textarea cols="30" rows="5" name="comments"></textarea><br />
<input type="submit">
</form>
This is my php insert code:
mysql_select_db("test", $db_server);
$sql="INSERT INTO users (Firstname, Lastname)
VALUES
('$_POST[firstname]','$_POST[lastname]')";
$sql="INSERT INTO comments (Comment)
VALUES
('$_POST[comments]')";
if (!mysql_query($sql,$db_server))
{
die('Error' . mysql_error());
}
echo "1 record added" ;
mysql_close($db_server);
and this is the error i'm getting:
Error: Cannot add or update a child row: a foreign key constraint fails
(test.comments, CONSTRAINT comments_ibfk_2 FOREIGN KEY
(useridfk) REFERENCES users (id) ON DELETE CASCADE ON UPDATE
CASCADE)
I am new to php and phpmyadmin so any help is appreciated.
First of all, you need to run the INSERT query on the users table so the user record is created.
mysql_select_db("test", $db_server);
$sql="INSERT INTO users (Firstname, Lastname)
VALUES
('$_POST[firstname]','$_POST[lastname]')";
mysql_query($sql);
if (!mysql_query($sql,$db_server))
{
die('Error' . mysql_error());
}
echo "1 record added" ;
You then need to retrieve the id of the newly created record on the users table
$newIdQuery = mysql_query("SELECT LAST_INSERT_ID() AS userId FROM users");
$newId = mysql_fetch_assoc($newIdQuery);
Then you can use that userId to add the comments, with the user id foriegn key properly populated.
Note: When building MySQL queries using the mysql_* functions, if you wrap a php variable in { } it will insert the value of the php variable into the SQL statement.
$sql="INSERT INTO comments (id, Comment)
VALUES
({$newId["userId"]}, '$_POST[comments]')";
if (!mysql_query($sql,$db_server))
{
die('Error' . mysql_error());
}
echo "1 record added" ;
mysql_close($db_server);
Ok so essentially what I'm trying to do is add a q&a component to my website (first website, so my current php knowledge is minimal). I have the html page where the user's input is recorded, and added to the database, but then I'm having trouble pulling that specific info from the database.
My current php page is pulling info where the questiondetail = the question detail (detail='$detail') in the database, but that could potentially present a problem if two users enter the same information as their question details (unlikely, but still possible, especially if the same person accidentally submits the question twice). What I want to do is have the page load according to the database's question_id (primary key) which is the only thing that will always be unique.
HTML CODE:
<form id="question_outline" action="process.php" method="get">
<p><textarea name="title" id="title_layout" type="text" placeholder="Question Title" ></textarea> </p>
<textarea name="detail" id= "detail_layout" type="text" placeholder="Question Details" ></textarea>
<div id="break"> </div>
<input id="submit_form" name="submit_question" value="Submit Question" type="submit" />
</form>
PROCESS.PHP CODE:
$name2 = $_GET['name2'];
$title = $_GET['title'];
$detail = $_GET['detail'];
$query= "INSERT INTO questions (title, detail) VALUES ('$title', '$detail')";
$result = mysql_query("SELECT * FROM questions where detail='$detail' ")
or die(mysql_error());
The info is being stored correctly in the database, and is being pulled out successfully when detail=$detail, but what I'm looking to do is have it pulled out according to the question_id because that is the only value that will always be unique. Any response will be greatly appreciated!
Updated Version
QUESTION_EXAMPLE.PHP CODE
<?php
$server_name = "my_servername";
$db_user_name ="my_username";
$db_password = "my_password";
$database = "my_database";
$submit = $_GET['submit'];
$title = $_GET['title'];
$detail = $_GET['detail'];
$conn = mysql_connect($server_name, $db_user_name, $db_password);
mysql_select_db($database) or die( "Unable to select database");
$result = mysql_query("SELECT title, detail FROM questions WHERE id =" .
mysql_real_escape_string($_GET["id"]), $conn);
$row = mysql_fetch_assoc($result);
mysql_close($conn);
?>
<h1><?php echo htmlspecialchars($row["title"]);?></h1>
<p><?php echo htmlspecialchars($row["detail"]);?></p>
Firstly, if that is code to be used in production, please make sure you are escaping your SQL parameters before plugging them in to your statement. Nobody enjoys a SQL injection attack. I would recommend using PDO instead as it supports prepared statements and parameter binding which is much much safer.
How can I prevent SQL injection in PHP?
So you have a form...
[title]
[details]
[submit]
And that gets inserted into your database...
INSERT INTO questions (title, details) VALUES (?, ?)
You can get the last insert id using mysql_insert_id, http://php.net/manual/en/function.mysql-insert-id.php.
$id = mysql_insert_id();
Then you can get the record...
SELECT title, details FROM questions WHERE id = ?
And output it in a preview page.
I have written an example using PDO instead of the basic mysql functions.
form.php:
<form action="process.php" method="post">
<label for="question_title">Title</label>
<input id="question_title" name="title"/>
<label for="question_detail">Detail</label>
<input id="question_detail" name="detail"/>
<button type="submit">Submit</button>
</form>
process.php:
<?php
// Create a database connection
$pdo = new PDO("mysql:dbname=test");
// Prepare the insert statement and bind parameters
$stmt = $pdo->prepare("INSERT INTO questions (title, detail) VALUES (?, ?)");
$stmt->bindValue(1, $_POST["title"], PDO::PARAM_STR);
$stmt->bindValue(2, $_POST["detail"], PDO::PARAM_STR);
// Execute the insert statement
$stmt->execute();
// Retrieve the id
$id = $stmt->lastInsertId();
// Prepare a select statement and bind the id parameter
$stmt = $pdo->prepare("SELECT title, detail FROM questions WHERE id = ?");
$stmt->bindValue(1, $id, PDO::PARAM_INT);
// Execute the select statement
$stmt->execute();
// Retrieve the record as an associative array
$row = $stmt->fetch(PDO::FETCH_ASSOC);
?>
<h1><?php echo htmlspecialchars($row["title"]);?></h1>
<p><?php echo htmlspecialchars($row["detail"]);?></p>
Without PDO...
form.php:
<form action="process.php" method="post">
<label for="question_title">Title</label>
<input id="question_title" name="title"/>
<label for="question_detail">Detail</label>
<input id="question_detail" name="detail"/>
<button type="submit">Submit</button>
</form>
process.php:
<?php
// Create a database connection
$conn = mysql_connect();
// Execute the insert statement safely
mysql_query("INSERT INTO questions (title, detail) VALUES ('" .
mysql_real_escape_string($_POST["title"]) . "','" .
mysql_real_escape_string($_POST["detail"]) . "')", $conn);
// Retrieve the id
$id = mysql_insert_id($conn);
// Close the connection
mysql_close($conn);
header("Location: question_preview.php?id=$id");
question_preview.php:
<?php
// Create a database connection
$conn = mysql_connect();
// Execute a select statement safely
$result = mysql_query("SELECT title, detail FROM questions WHERE id = " .
mysql_real_escape_string($_GET["id"]), $conn);
// Retrieve the record as an associative array
$row = mysql_fetch_assoc($result);
// Close the connection
mysql_close($conn);
?>
<h1><?php echo htmlspecialchars($row["title"]);?></h1>
<p><?php echo htmlspecialchars($row["detail"]);?></p>
I assume you want to sort the questions according to the question_id. You could try using the ORDER BY command
example -
$result = mysql_query("SELECT * FROM questions where detail='$detail' ORDER BY question_id")
For these type of examples, you need to run Transaction within database
below are the
http://dev.mysql.com/doc/refman/5.0/en/commit.html
Or else
Create an random variable stored in session and also insert into database and you call it from database and you can preview it easily.
id | question_code | q_title
question_code is the random value generated before insertion into database,
and save the question_code in a session and again call it for preview.
I'm trying to update a table from a form.
I have 3 pages. The first one queries all of the rows from my table with an "edit" link.
When edit is clicked (page 2) the code pulls the $id and puts it in the url. The $id is pulled from the url and is used in a query to fill a form.
My problem is passing the updated form info to my table. Basically the update isn't happening.
Second page
<?php
include '../db/config.php';
include '../db/opendb.php';
$id = $_GET["id"];
$order = "SELECT * FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
?>
<form method="post" action="edit_data.php">
<input type="hidden" name="id" value="<?php echo "$row[id]"?>">
<tr>
<td>Title</td>
<td>
<input type="text" name="title" size="20" value="<?php echo"$row[title]"?>">
</td>
</tr>
<tr>
<td>Post</td>
<td>
<input type="text" name="post" size="40" value="<?php echo
"$row[post]"?>">
</td></tr>
<tr>
<td align="right">
<input type="submit" name="submit value" value="Edit">
</td>
</tr>
</form>
third page
include '../db/config.php';
include '../db/opendb.php';
$query = "UPDATE tableName SET '$_POST[title]', '$post[post]' WHERE id='$id'";
mysql_query($query);
It should be
UPDATE tableName SET `title` = {$_POST['title']}, `post` = {$_POST['post']}...
Ask yourself, what are you setting?
Your SQL statement for the database update is wrong. It should include a listing of not only the new values but also the corresponding field names. This means it should look more like this:
$query = "UPDATE tableName SET `title` = {$_POST['title']}, `post` = {$_POST['post']} WHERE id = '$id'";
Notice that you also should embrace fields of $_POST inside of strings with curly brackets ({}) or put them outside of the quotes. (like " = " .$_POST['title']. ", "). This is absolutely necessary if you use the standard way to access those with he quotes (e.g. not $_POST[title] but $_POST['title'] or $_POST["title"]).
Additionally you should add the following to your code:
Some error handling, currently you don't even know if something went wrong. The simplest way is to check the return value of the mysql_query() function for null and if it is null, get the mysql error message with mysql_error().
Escaping for passed values. Currently you directly pass the posted data into a mysql query which is very insecure. (See for example SQL-Injection on wikipedia) You should use mysql_real_escape_string() on all form data before inserting them into queries. This escapes all parts that could be malicious.
if (isset($_POST[title])){
$title = mysql_real_escape_string(trim($_POST['title']));
}else{
$title = NULL;
}
if (isset($_POST[post])){
$post = mysql_real_escape_string(trim($_POST['post']));
}else{
$post = NULL;
}
$query = "UPDATE tableName SET title='$title', post='$post' WHERE id='$id'";
mysql_query($query);
I would also recommend mysqli functions instead of mysql and I probably wouldn't call a variable and table column 'post' to avoid confusion.
That is because you are not setting the values. In the statement:
$query = "UPDATE tableName SET '$_POST[title]', '$post[post]' WHERE id='$id'";
you should pass column names to be updated.
If you are not using PDO statements yet to prevent SQL injection attacks then you should use more protection then just mysql_real_escape_string(). On top of escaping the data you should be validating that the submitted data is in fact what you are expecting.
Ie. In your code here:
$id = $_GET["id"];
$order = "SELECT * FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
If you added:
if(is_numeric($_GET['id'])){
$id = mysql_real_escape_string(trim($_GET["id"]));
$order = "SELECT id, title, post FROM tableName where id='$id'";
$result = mysql_query($order);
$row = mysql_fetch_array($result);
}
This would at least validate what you are executing is in fact an ID number (That is, if ID is actually a number ;) . You can apply this logic to all your inputs if you are not yet using PDO statements. If you are expecting letters then validate for letters, numbers validate for numbers, escape special characters. Again, this is bare minimum. I would really suggest reading up on the hundreds of SQL injection techniques and start reading up on PDO's.
Also, in regards to using the SELECT * statement. I would try and avoid it. It adds a layer of vulnerability to your statements, if you change the order of the fields in your table and you are using $row[0] (Numbered requests) it can muck things up and lastly if your table contains additional fields with data that is unrelated to the ones you need then you are using on this page then you are loading information you don't need to.
$order = "SELECT id, title, post FROM tableName where id='$id'";
Would solve that nicely. :) Good luck!