I’m trying to update multiple rows in a mysqli table from an HTML form. The data seems to be getting from the form to my "update database" page. But it’s not going into the database.
Here’s the relevant part of the form:
for($i=0;$i<$rowcount;$i++)
{
$row = mysqli_fetch_array($result);
echo "<tr>
<td> $row[SubFirstName] $row[SubLastName] </td>
<td> $row[PerfFirstName] $row[PerfLastName] </td>
<td style='display:none'><input type='text' class='input' name='PerformerID[]' value= '$row[PerformerID]' /> Years</td>
<td><input type='text' class='input' size= '5' name='GKYears[]' value= '$row[GKYears]' /> Years</td>
</tr>";
}
And here’s the code to insert the values into the database:
for($i=0;$i<$count;$i++)
{
mysqli_query($con, "UPDATE Performers SET
GKYears = '$_POST[GKYears][$i]'
WHERE PerformerID = '$_POST[PerformerID][$i]'");
}
When I do a var_dump of the POST data, it all seems to be there. Can someone explain how to fix this, and why it’s wrong? I’ve got other more complex variants of the same issue for the other pages.
Bad structure. Don't use CSS to simulate a hidden form field, and you don't even need the hidden field:
echo <<<EOL
<tr>
<td>... name stuff ...</td>
<td>... perf stuff ...</td>
<td><input type="text" name="GKYears[{$row['PerformerID']}]" value="{$row['GKYears']}" /></td>
</tr>
EOL;
Note how the ID value gets embedded in the field name, so you'll end up with
<input ... name="GKYears[42]" ... />
<input ... name="GKYears[103]" ... />
Then your PHP-side stuff becomes simply:
foreach($_POST['GKYears'] as $rowID => $value) {
... update db for record Id $rowID with value $value
}
Beyond that, your code is gaping wide and just begging for an SQL injection attack.
Related
I am currently trying to design an invoice generator. Essentially the page has input fields along side a table which allows you to create extra rows to input more data.
I need this data to be stored in database to be called in the future to be turned into a downloadable .pdf
My current issue is getting the data from the table into the database. So far my code only inputs the first row of data. Am i going the complete wrong way about this?
<tr id="item0" class="item">
<td>
1
</td>
<td>
<input name='item_name[0]' type='text' placeholder='Name' class='form-control input-md' />
</td>
<td>
<input name='quantity[0]' type='text' placeholder='0' class='form-control input-md' />
</td>
<td>
<input name='price[0]' type='text' placeholder='£0.00' class='form-control input-md' />
</td>
<td>
total
</td>
</tr>
<tr id="item1" class="item">
<td>
1
</td>
<td>
<input name='item_name[1]' type='text' placeholder='Name' class='form-control input-md' />
</td>
<td>
<input name='quantity[1]' type='text' placeholder='0' class='form-control input-md' />
</td>
<td>
<input name='price[1]' type='text' placeholder='£0.00' class='form-control input-md' />
</td>
<td>
total
</td>
</tr>
And the php...
if (isset($_POST['submit'])) {
print_r(array_values($_POST['item_name']));
}
$i = 0;
foreach($_POST as $val) {
$item_name = $_POST['item_name'][$i];
$quantity = $_POST['quantity'][$i];
$price = $_POST['price'][$i];
$sqlConnect - > query("INSERT INTO `Invoices` (`id`, `item_name`, `quantity`, `price`) VALUES ('".$i.
"', '".$item_name.
"', '".$quantity.
"', '".$price.
"')");
$i++;
}
}
else {
die('No item data to process');
}
Assuming the id field is an auto-incrementing primary key of your Invoices table: Leave that one, when inserting. Your current code always tries to insert 1 or 2 as id for every request.
If its not an auto-increment you need to generate a valid id in your app, $i alone won't do the trick.
foreach ($_POST['item_name'] as $index => $itemName) {
$quantity = $_POST['quantity'][$index];
$price = $_POST['price'][$index];
// DONT DO THIS! Its prone to SQL injection
$sqlConnect->query("INSERT INTO `Invoices` (`item_name`, `quantity`, `price`) VALUES ('".$itemName.
"', '".$quantity.
"', '".$price.
"')");
}
Not sure what your db-connection library is, but currently your code is prone to SQL injection attacks. You should use prepared statements and parameterization. Please see what Bobby Tables says.
To have a real dynamic form, where undefined number of items can be entered, you need JavaScript.
but for now, I would suggest to change your form to something like this:
<input name='items[1][name]'>
<input name='items[1][quantity]'>
<input name='items[1][price]'>
<!-- and for second item: -->
<input name='items[2][name]'>
<input name='items[2][quantity]'>
<input name='items[2][price]'>
so your $_POST data structure will be like this:
items:[
[
quantity:
price:
name:
],
[
quantity:
price:
name:
],
]
This way, you can loop through items, not item properties. and your loop will be like this:
if (isset($_POST['submit'])) {
var_dump($_POST);
foreach($_POST['items'] as $item){
$sql = 'INSERT INTO invoices (name, quantity, price)
VALUES ($item['name'], $item['quantity'], $item['price'])';
$sqlConnect->query($sql);
}
} else {
die('No item data to process');
}
Note that in MySQL you can set id field to auto_increment, so no need to include it in your query.
Also, use var_dump() to know what you are dealing with, like var_dump($_POST);
Dunno if the title makes sense, but I have a variable which would to put it in basic terms would be called like this:
$_POST['something'+$variable2]
I have a form which is for editing selected records, this form contains entries for all previously selected records:
<form name="input" action="editcar.php" method="POST">
<input type="submit" value="Yes">
while($row = mysqli_fetch_assoc($result))
{
echo'
</div>
<table style="color:white">
<tr>
<td style="text-align:right">Manufacture:</td><td><input type="text" name="manufacture'.$row['carIndex'].'" value="'.$row['make'].'"></td>
<td style="text-align:right">Model: </td><td><input type="text" name="model'.$row['carIndex'].'" value="'.$row['model'].'"></td>
</tr>
<tr>
<td style="text-align:right">Colour: </td><td><input type="text" name="colour'.$row['carIndex'].'" value="'.$row['colour'].'"></td>
<td style="text-align:right">Reg: </td><td><input type="text" name="reg'.$row['carIndex'].'" value="'.$row['Reg'].'"></td>
</tr>
<tr>
<td style="text-align:right">Price: </td><td><input type="text" name="price'.$row['carIndex'].'" value="'.$row['price'].'"></td>
<td style="text-align:right">Mileage: </td><td><input type="text" name="mileage'.$row['carIndex'].'" value="'.$row['miles'].'"></td>
</tr>
<tr>
<td style="text-align:right">Max MPH: </td><td><input type="text" name="mph'.$row['carIndex'].'" value="'.$row['mph'].'"></td>
<td style="text-align:right">MPG: </td><td><input type="text" name="mpg'.$row['carIndex'].'" value="'.$row['mpg'].'"></td>
</tr>
</table>
</form>
</div> ';
}
?>
</form>
The form is looped for each record previously chosen, to enable mass editing. The isue arouses when I realised I'd have multiple inputs with the same name, so I did:
<input type="text" name="model'.$row['carIndex'].'" value="'.$row['model'].'">
Placing the primary key of the record it was currently tired to on the end of it's name. Which seemed like a logical way to go about things.
However now I need to call these variables to place in the mysql query and I dunno how to do that, or even if I can.
I have the selected records saved in an array so I have:
foreach ($postid as $carID)
{
$query = "stuff";
mysqli_query($db, $query);
}
Each loop has $carID containing the variables that was put on the end of the form input names.
So something like:
$_POST['something'+$variable2]
is all I can think of but doesn't work.
Any method that works for my overall code is welcome not just a solution to the issue I've made.
Actually your way should work. Just replace the + with . in $_POST['something'+$variable2].
My tip is: use an array as name in your html instead:
<input type="text" name="model[]" value="'.$row['model'].'">
On php-Side you can loop through all $_POST['model'] since its an array now.
You can add the index for every entry in your html, too:
<input type="text" name="model['.$row['carIndex'].']" value="'.$row['model'].'">
PHP uses a dot for concatenation, not + like Java and Javascript:
$_POST['something' . $variable2]
Try something like this:
<form ...>
<?php
while($row = mysqli_fetch_assoc(...):
$index = $row['carIndex'];
?>
<input type="text" name="carmodel[<?php echo $index?>][model]" value="<?php echo $row['model'] ?>">
<?php endforeach; ?>
</form>
This way you will have the data stored in $_POST['carmodel'] as an array indexed by carIndex value as the structure of data in $_POST is defined by names of inputs, here you will have names likee carmodel[1][model] for example so then in post it will be in $_POST['carmodel'][1][model]
you can read here as well
How would I create this array structure in an HTML form?
I am trying to create a table showing multiple users data. The data in the table will then be able to be edited and updated. Below is an example of the way the form is laid out:
echo "<form action=AdminUpdateLecInfo.php method=post>";
while ($return = mysql_fetch_assoc($result)) {
$phonenumber = "$return[PhoneNumber]";
$number = str_pad($phonenumber, 11, "0", STR_PAD_LEFT);
echo " <tr class='data'>
<input type='hidden' name='id'".$return['ID']."'' value= '".$return['ID']."' />
<td class = 'title'><input class = 'title' type='text' name='title'".$return['ID']."'' value= '".$return['Title']."' /></td>
}
echo "</table>
<input class='submit' type='submit' value='Update Info' />
</form>
Once the table is created the information is passed to the 'update.php' script.
$sql="UPDATE completeinfo SET Title='".$_POST['title'][$return['ID']]."'
WHERE ID = '".$_POST['id'][$return['ID']]."'";
header("Location:Home.html");
The problem I'm having is that I need to add the '".$return['ID']."' to the name of each input field so that not all users details are updated with the same values. I am unsure if I need to apply a foreach loop around this query so that it applies to each user and updates their details. Currently however the update query is not working presumably because the post method is not fetching the values from the form correctly.
Your problem is the name of your fields, use that :
$return_id = $return['ID'];
echo "
<tr class='data'>
<td class = 'title'>
<input type='hidden' name='id$return_id' value='$return_id' />
<input class='title' type='text' name='title$return_id' value='$return_id' />
</td>
</tr>";
Before doing your mysql update, do var_dump($_POST);, you'll be shown the content of the HTTP POST parameters so you can see what they are and how to use them in the query.
You have to use the names of your text fields as array so you can iterate your array
name='title'".$return['ID']."'
name='id'".$return['ID']."'
I seem to have an issue inserting the post values into my database, and i don't see the error in the coding. I've been looking at it for a while now and to me everything looks right, however when i use the form and submit the data the page reload but no data get inserted into the database.
It would be much appreciated if someone could help me identify the error in the coding.
If you have any questions feel free to ask!
Kind regards Jim
FORM
<?php
//Show the form if the user is a Admin
if(isset($_SESSION['username'])){
$username == $_SESSION['username'];
$results = $mysqli->query("SELECT authority FROM users WHERE username='$username' LIMIT 1");
while($row = $results->fetch_object()){
$aut = $row->authority;
}
}
if($aut == 1){
?>
<form action="index.php" method="post">
<table>
<tr>
<td> Title: </td>
<td><input type="text" name="title"></td>
</tr>
<tr>
<td valign="top"> News: </td>
<td><textarea name="information"></textarea></td>
</tr>
<tr>
<td> <input type="hidden" value="news"> </td>
<td><input type="submit"></td>
</tr>
</table> <hr>
</form>
MYSQLI
<?php
}
//Insert into the database
if(isset($_POST['news'])){
$title = $_POST['title'];
$information = $_POST['information'];
$mysqli->query("INSERT INTO `news` (`title`, `information`) VALUES ( '".$title."', '".$information."')");
}
<input type="hidden" value="news"> should be <input type="hidden" name="news">
That's why isset($_POST['news']) will never be true.
Beside that silly typo problem your code suffers from two real disasters.
You have no error reporting, which renders you helpless against such silly mistakes
You are adding your data directly into query, while ought to use placeholders for that.
I am not sure what was intended with the backticks and periods in your original query. In my limited experience my queries take the form of:
$mysqli->query("INSERT INTO news(title, information) VALUES ('$title', '$information')");
I would say that priority #1 is getting some debugging information in the form of return values for your php functions or access to php error logs.
I have a small section of code. When the table is empty this code works fine and enters in to the table fine. But then if i try again then this fails with the error?
What am i doing wrong?
Thanks
// On my Function page
function admin(){
connect();
$query = mysql_query("INSERT INTO results
(t_id, pos1, pos2, pos3)
VALUES ('$_POST[t_id]','$_POST[pos1]','$_POST[pos2]','$_POST[pos3]')")
or die ("Error.");
$b = "Updated fine</b></a>.";
return $b;
exit();
}
// Then on my main page
<?php
include ('functions.php');
if (isset($_POST['admin'])){
$admin = admin();
}
?>
<div id="content">
<div id="admin">
<form action="" method="post">
<table width="100%" border="0" align="center" cellpadding="3" cellspacing="1">
<tr>
<td width="100%"><?php echo "$admin"; ?></td>
</tr>
<tr>
<td width="100%"><label>Track <input type="text" name="track" size="25" value="<? echo $_POST[t_id]; ?>"></label></td>
</tr>
<tr>
<td width="100%"><label>Position 1<input type="text" name="pos1" size="25" value="<? echo $_POST[pos1]; ?>"></label></td>
</tr>
<tr>
<td width="100%"><label>Position 2 <input type="text" name="pos2" size="25" value="<? echo $_POST[pos2]; ?>"></label></td>
</tr>
<tr>
<td width="100%"><label>Position 3 <input type="text" name="pos3" size="25" value="<? echo $_POST[pos3]; ?>"></label></td>
</tr>
<tr>
<td width="100%"><input class="save" type="submit" value="" name="admin"></td>
</tr>
</table>
</form>
</div>
</div>
Without seeing your table schema, I can only think you have UNIQUE t_id and you want to insert the same ID into it.
Several way to debug:
Use or die ("Error: " . mysql_error()); instead of just or die ("Error.");
Check your table schema: SHOW CREATE TABLE tablename and write it down on your question, so we can see if it's causing error.
It is hard to guess. Maybe you are entering the same values twice, and they happen to violate some unique constraint?
But you make another mistake: you forget to call mysql_real_escape(). That is bad.
Can you tell us of the error? It sounds like you're hitting a primary key violation, perhaps by trying to insert the same id more than once.
That aside, your code is riddled with security holes.
You should not be inserting variables straight from the POST into your query. All I have to do is submit '; DROP DATABASE and I can completely wreck your system.
Additionally, you're injecting values directly from POST into input fields, meaning I can set up a button on my site that submits " <script type='text/javascript'>window.location='http://mysite.com'</script> or something along those lines and take over your page.
This may sound terse, but you should do some googling or pick up a book regarding textbook security issues with websites.
EDIT: Just saw your comment about learning security. My advice is to be proactive about this sort of thing, because being reactive is often too late to fix problems.