getting plain array text when updating mysql record - php

so i have table with fields like this, i want to be able to edit each username/email etc if check box selected.
echo '<td><input type=checkbox name=checkbox[] value='. $row['Id'] .' ></td>';
echo '<td><input type=text name=username[] value='. $row['username'] .' ></td>';
echo '<td><input type=text name=email[] value='. $row['email'] .' ></td>';
echo '<td><input type=text name=adress[] value='. $row['adress'] .' ></td>';
and this is my script, i get array plain text as result from each input, btw Im using query for email only to test first
if(isset($_POST['edit']))
{
if(isset($_POST['checkbox'])) {
$id_array = $_POST['checkbox'];
$id_count = count($_POST['checkbox']);
for($i=0; $i < $id_count; $i++) {
$id = $id_array[$i];
$query = ("UPDATE members SET email = '". $_POST['email'] ."' WHERE ID = '". $id ."'");
$result = $conn->query($query);
if($result) {
echo "ok";
}
else {
echo "<br><br>Error: " . $conn->error;
}
}
}
}

First off, you are vulnerable to sql injection attacks. Enjoy having your server pwn3d.
Secondly, you're stuffing your POST array directly into the query, which is incorrect. Since you're using the [] naming hack in the form fields, $_POST['email'] is going to be an ARRAY of values from your form, and you need something more like
.... VALUES ('$_POST[email][$i]', ...)
^^^^
(note the extra array index) to access the individual values in that sub-array.
Remember, for PHP, using an array in a string context gives you the literal word Array, and not the array's contents:
$foo = array(1,2,3);
echo "$foo"; // outputs 'Array'
echo "$foo[1]"; // outputs '2'

Related

Updating multiple rows the same table in a webform populated using PHP and SQL

My aim is to create a dynamic webpage that returns all of the records in a table meeting a given criteria and uses them to populate a webform. The user can then make changes as they wish and update the entire table with a single button press.
In the example below I'd like to list all the events, the start time will appear in an editable text box and when I press submit it should update all the values.
I've created a mock-up below:
$query = "SELECT * FROM Events";
$result = mysqli_query( $dbc, $query ) ;
if ( mysqli_num_rows( $result ) > 0 )
{
echo '<form action="update_events.php" method="post">>';
echo '<table><tr>';
while ( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ))
{
echo '<td>' . $row['Event_Name'] .' </td>'.
'<td>' . $row['Event_Date'] .'</td>'.
'<td><input name="'. $row['Event_ID'] .'" type="text" value="'$row['Event_Start_Time'] .'"></td>';
echo '</tr>';
}
echo '</table>';
echo ' <input type="submit" value="Submit"></form>';
mysqli_close( $dbc ) ;
}
else
{
echo '<p>There are currently no events.</p>' ;
}
I cannot figure our how to get the processing on the update_events.php to work, any help would be appreciated.
foreach(????){
$sql = "UPDATE Events SET Event_Start='$Event_Start' WHERE id='$Event_ID'";
mysqli_query($dbc, $sql)
}
You really want to keep your POST variables static, it makes life easier. Don't try and use one variable to store two values, give them one each.
As you are submitting multiple values to the server which you want to loop over then it makes sense to submit them in arrays, so something like this:
$i=0;
while ( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ))
{
echo '<td>' . $row['Event_Name'] .' </td>'.
'<td>' . $row['Event_Date'] .'</td>'.
'<td><input name="event['.$i.'][start]" type="text" value="'$row['Event_Start_Time'] .'"><input name="event['.$i.'][ID]" type="hidden" value="'. $row['Event_ID'] .'"></td>';
echo '</tr>';
$i++;
}
Now your form will submit all the events as a multidimensional array which you can retrieve in $_POST['event'] and loop over it to do your database updates like this:
$stmt = $this->mysqli->prepare("UPDATE Events SET Event_Start=? WHERE id=?");
$stmt->bind_param('ss', $start, $id);
foreach ($_POST['event'] as $event) {
$start = $event['start'];
$id = $event['ID'];
$stmt->execute();
}
This code uses a prepared statement for the database insert, the method you are using is insecure and leaves you vulnerable to SQL injection. You should read up on Mysqli prepared statements and start using them.

How to store the names of checkboxes of a form to a php arrray

First off, I want to store the names of these checkboxes which are submitted, and not their values.
This is my code:
<?php
$con=mysqli_connect("localhost","root","","notifier");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM student");
echo "Enter the attendance. Please untick for 'ABSENT' students and submit";
echo "<br>";
echo "<form action=\"d.php\" method=\"post\">";
while($row = mysqli_fetch_array($result))
{
echo "<br>" .$row['classrollno'] . "&nbsp &nbsp<input type=\"checkbox\" name=\"" . $row['studentid'] . "\" value=\"P\" checked>";
}
echo "<input type=\"submit\" name=\"submit\" value=\"submit\">";
echo "</form>";
?>
This code simply fetches a column of student rollnumberss from student table, prints them, and as well as prints a checkbox infront of them which is checked by default.
Names of checkboxes will be the student id (varchar, another column).
Now since All Checked checkboxes, that is the checboxes which will be submitted to next page will have same default value "P", I m not concerned about their values.
How do I store the names of these checkboxes in an array, and later on use it to perform updation in table for all these student id's?
Use the following code:
while($row = mysqli_fetch_array($result))
{
echo '<br>' .$row['classrollno'] . ' <input type="checkbox" name="studentId[]" value="' . $row['studentid'] . '" checked />';
}
Then, when you process the form, the $_POST['studentId'] variable will contain an array with all the id's.
Since the value that will probably be inserted in the db is 'P' for every student, you wouldn't need to include it in your form, but just hardcode it in your query.
Keep adding the names to an array. Its straight forward.
Declare $allStudentIds = array(); outside while loop. Then, to store in that array,
$allStudentIds[] = $row['studentid'];
Since you wanted to use these values later, you can directly store them inside a session variable:
$_SESSION['allStudentIds'][] = $row['studentid'];
In above case, $_SESSION['allStudentIds'] will be an array of all student ids selected.
Note: You need to start session using session_start() as the first line in the script after opening <?php tag.
Simply, in the fetching while loop, define an array and set each checkbox value to one of its elements then assign it as a session variable:
while($row = mysqli_fetch_array($result))
{
echo "<br>" .$row['classrollno'] . "&nbsp &nbsp<input type=\"checkbox\" name=\"" . $row['studentid'] . "\" value=\"P\" checked>";
$names[] = $row['studentid'];
}
Then,
$_SESSION['names'] = $names;
Your confusion seems to stem from the fact that you are mixing the View (the name of the checkbox in HTML) and the Model/Data (which the student_id you are getting from your DB query ie. the $row = mysqli_fetch_array($result) in the while loop).
All you need to do is create an empty array (eg. $studentid_arr) before the loop and after the echo statement which is just contributing to the view (the HTML) you do some work with your data. What you want to do currently is to store the student_ids (and not the name of the checkbox) in your $studentid_arr.
That can be done with a simple array_push ($studentid_arr,$row['studentid']);
So your while loop would look like
while($row = mysqli_fetch_array($result))
{
echo "<br>" .$row['classrollno'] . "&nbsp &nbsp<input type=\"checkbox\" name=\"" . $row['studentid'] . "\" value=\"P\" checked>";
array_push ($studentid_arr,$row['studentid']);
}
Now you can just POST this PHP array to your next script which is expecting these values. (which is what I assume you mean by submitting to the next page)

How can $_POST pass input variables to MySQL query as integers, not 1?

I have a table of numbers where the user should be able to edit the values and have the database updated on submit.
So far, my faulty code is updating every field with the value 1 on submit, regardless of what has been inputted.
Code on submit:
//If the confirm button has been hit:
if (isset($_POST['submit'])) {
//Create the foreach loop
foreach($_POST['classtoupdate'] as $classes){
//Grab the POST data and turn it into integers
$class_id = (int)$classes;
$totalspcs = (int)$_POST['allspaces'];
$totalbkgs = (int)$_POST['allbookings'];
$newbies = (int)$_POST['noobs'];
//Change the booking numbers:
$newdeets = "UPDATE classes SET total_spaces = '$totalspcs', total_bookings = '$totalbkgs', free_spaces = ('$totalspcs' - '$totalbkgs'), newbies = '$newbies' WHERE class_id = '$class_id')";
echo $newdeets;
mysqli_query($dbc, $newdeets);
}
mysqli_close($dbc);
echo 'All good, yay! Go look';
}
Form:
//create the form
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '" >';
echo '<tr><td>' . $class . '</td>';
echo'<td>' . $new_date . '</td>';
echo '<td>' . $new_time . '</td>';
echo '<td><input type="text" maxlength="2" class="input-mini" name="noobs[]" id="noobs[]" value="' . $newbies . '">';
echo '<td><input type="text" maxlength="2" class="input-mini" name="allspaces[]" id="allspaces[]" value="' . $totalspaces . '">';
echo '<td><input type="text" maxlength="2" class="input-mini" name="allbookings[]" id="allbookings[]" value="' . $bookings . '"
>';
echo '<td>' . $freespaces . '</td>';
echo' <input type="hidden" name="classtoupdate[]" id="classtoupdate[]" value="' . $class . '" />';
}
echo'</table>';
// Make booking button
echo '<input type="submit" name="submit" class="btn btn-large btn-primary pull-right" value="Update">';
echo '</form>';
The echoed query results after inputting random values (not 1) in the form:
UPDATE classes SET total_spaces = '1', total_bookings = '1', free_spaces = ('1' - '1'), newbies = '1' WHERE class_id = '26')
UPDATE classes SET total_spaces = '1', total_bookings = '1', free_spaces = ('1' - '1'), newbies = '1' WHERE class_id = '16')
..and so on for each table row. I can't find the problem replicated after extensive searching on SO and in the manuals.
I've tried intval(), serialize and array_map on the POST results (probably incorrectly); I've tried different foreach loops to translate them into integers, still no joy.
Any advice?
try this:
foreach($_POST['classtoupdate'] as $index => $classes){
and
$totalspcs = (int)$_POST['allspaces'][$index];
$totalbkgs = (int)$_POST['allbookings'][$index];
$newbies = (int)$_POST['noobs'][$index];
note the $index in each line.
$i=0;
//Create the foreach loop
foreach($_POST['classtoupdate'][$i] as $classes){
//Grab the POST data and turn it into integers
$class_id = (int)$classes;
$totalspcs = (int)$_POST['allspaces'][$i];
$totalbkgs = (int)$_POST['allbookings'][$i];
$newbies = (int)$_POST['noobs'][$i];
//Change the booking numbers:
$newdeets = "UPDATE classes SET total_spaces = '$totalspcs', total_bookings = '$totalbkgs', free_spaces = ('$totalspcs' - '$totalbkgs'), newbies = '$newbies' WHERE class_id = '$class_id')";
echo $newdeets;
mysqli_query($dbc, $newdeets);
$i++;
}
your POST variables are arrays (e.g. allspaces[])
so, this assignment is always giving you 1 as a result, because you're trying to cast an array to integer.
$totalspcs = (int)$_POST['allspaces'];
you should cycle your array and use the data in a different way.
If you don't need an array, get rid of the square brackets in the input name.
The problem is with the way you have named your input fields. <input type="text" maxlength="2" class="input-mini" name="noobs[]"> The [] means that the data will be posted back to the server as an array, and you are type casting an array into an integer, which is why everywhere you are getting 1 as value. Lose the [], eg. <input type="text" maxlength="2" class="input-mini" name="noobs"> should fix the problem.
I made an example you should be able to use to solve your problem.
<?php
$foo = array('1','2','3');
$bar = array('4','5','6');
// Simulates the $_POST variable
$baz = array('foo'=>$foo, 'bar'=>$bar);
// You should ensure that all entries have an equal length before iterating through!
if(count($baz['foo']) === count($baz['bar'])){
foreach($baz['foo'] as $key=>$value){
$x = (int)$value;
$y = (int)$bar[$key];
var_dump($x, $y);
}
}
?>
The problem that you're having is that, even though you're looping through $_POST['classtoupdate'], you are still using $_POST['allbookings'] and other fields which are still arrays.
Converting an array to an integer value will always return 1 if the array is not empty. So you'll have to extract the values from them.

Display checkbox values in HTML after select, submit and email results from process.php

I have a checklist that's broken down into days, stage, timeShow, and bandName. I am displaying the options from a database with this script and I'm trying to display the results (and eventually email them) to the user on the 'process' page. How do I carry over the $result_x to the following page?
Here's an example of one of the 'blocks' for Saturday, Stage 1 and the value of the selection is the 'ID' of the row.
UPDATE- Part one is solved. Now looking to get the results sent to an email address input by the user.
FORM SOLUTION- 'Selection.php'
$sql_Sat1 = "SELECT * FROM bandSched WHERE day='saturday' AND stage='stage 1'";
mysql_query($sql_Sat1);
$result_Sat1 = mysql_query($sql_Sat1);
while($row = mysql_fetch_array($result_Sat1))
{
echo "<ul><li>";
echo'<input type="checkbox" name="id[]" value="'.$row['id'].' " id="bandSched_' . $row['id'] . '" />';
echo '<label for="bandSched_' . $row['id'] . '">' . $row['timeShow']." ".$row['bandName'] . '</label>';
echo "</li></ul>";
}
SOLUTION- 'process.php'
if ( ! empty($_POST['id']))
{ foreach($_POST['id'] as $key => $id) { $_POST['id'][$key] = mysql_real_escape_string($_POST['id'][$key]); }
$in = implode(', ', $_POST['id']);
$sql_Sat2 = "SELECT * FROM bandSched WHERE id IN ($in) ORDER BY FIELD(id, $in)";
$result = mysql_query($sql_Sat2) or die('MySQL Error ' . mysql_errno() . ': ' . mysql_error());
}
if ( ! isset($result))
{
echo 'You did not select anything';
}
else
{
while ($row=mysql_fetch_assoc($result))
{
echo "<tr>";
echo "<td>". $row['timeShow'] ."</td><td>" . $row['bandName'] . "</td>";
echo "</tr>";
}
}
Unless you have the attribute checked="checked" in your <input type="checkbox" />, the value will not be sent with the form data.
Try this:
echo '<input type="checkbox" value="' . $row['id'] .'"name="selected" checked="checked" />';
Does this solve the problem?
Carrying data from page to page can either be done with Sessions, Cookies, or posting hidden form elements containing the data.
Sessions provide you the data, but you still need to make a valid query. The only thing that sessions do are store data on the server. They do not keep any of the program execution, variables, etc.
Your error message is telling you that mysql_fetch_array was not supplied a MYSQL result resource (and it wasn't you supplied it an integer of the id value). The query will not be remembered across the session.
Also, mysql_* is deprecated, use PDO or mysqli.

PHP checkbox problem

I am going nuts here, I have an array of checkboxes from a form that I am trying to $_POST with PHP. EVERYTHING on my form posts fine except the check boxes. The checkboxes DO post, but in the wrong order. For instance when I want checkbox[0] and checkbox[2] I actually get checkbox[0] and checkbox[1].
I have tried many different ways to get the value of the checkbox, including isset but I still have the same problem. I just need the checkbox value of on to be stored in my database if the checkbox is indeed checked.
My code is below. $in_production is the checkbox. I can provide the code that generates the checkbox too if it is needed.
Thanks in advance.
if ($_GET['action'] == 'Edit_Product'){
include("../dbinfo.php");
$q_id = $_GET['q_id'];
for ($i = 0; $i < count($_POST['p_id']); $i++){
$result = mysql_query('SELECT * FROM products WHERE q_id = '.$q_id);
$num = mysql_num_rows($result);
$p_id = ($_POST['p_id'][$i]);
$in_production = ($_POST['in_production'][$i]);
$p_name = ($_POST['p_name'][$i]);
$p_price = ($_POST['p_price'][$i]);
$p_name_conflict = FALSE;
for ($ii = 0; $ii < $num; $ii++){
$row = mysql_fetch_array($result);
$p_name_conflict_check = $row['p_name'];
$p_id_conflict_check = $row['p_id'];
if($p_name_conflict_check == $p_name &&
$p_id_conflict_check != $p_id){
$p_name_conflict = TRUE;
}
}
if ($p_name_conflict == FALSE){
$query = "UPDATE products SET p_name='$p_name',
p_price='$p_price', in_production='$in_production',
last_modified=CURDATE() WHERE p_id = '$p_id'";
mysql_query($query);
}
else{
$update_failures =+1;
}
}
mysql_close($link);
if($update_failures == 0){
header("Location: Products_Updated.html");
}
elseif ($update_failures != 0){
header("Location: Products_Exist.php?update_failures=".$update_failures);
}
}
P.S. I don't know why but the code block icons are not present on SO right now... so my code is not all pretty. Also, I know my code is horribly inefficient, but I am just trying to get this working right now, then fine tune later. I am open to efficiency suggestions as well, but that is not my primary objective with this question.
EDIT: Here is the form from the HTML...
<form id="form" name="form" method="post" action="/Management/Products/Product_Management.php?action=Edit_Product&q_id=<?php echo "$q_id" ?>">
<?php
include("../dbinfo.php");
$result = mysql_query('SELECT * FROM products WHERE q_id =' . $q_id);
$num = mysql_num_rows($result);
mysql_close($link);
for ($i = 0; $i < $num; $i++){
$row = mysql_fetch_array($result);
$p_id = $row['p_id'];
$p_name = $row['p_name'];
$p_price = $row['p_price'];
$in_production = $row['in_production'];
$date_added = $row['date_added'];
$last_modified = $row['last_modified'];
if($in_production == 'on'){
$checked = 'checked';
}
else{
$checked = '';
}
echo "<div>Product ID# " . $p_id . "<label style=\"font-style:italic\"> (Originally added on " . $date_added . ", last modified on " . $last_modified . ")</label></div><br/>";
echo "<input id=\"p_id" . $p_id . "\" class=\"text\" type=\"hidden\" name=\"p_id[]\" value=\"" . $p_id . "\"/>";
echo "<label>Product Name *</label><br/>";
echo "<div><label style=\"font-style:italic\">(Product still in production <input type=\"checkbox\" name=\"in_production[]\"" . $checked . " style=\"width:15px\"/>)</label></div>";
echo "<input id=\"p_name" . $p_id . "\" class=\"text\" type=\"text\" name=\"p_name[]\" maxlength=\"20\" onfocus=\"on_focus(this)\" onblur=\"on_blur(this)\" value=\"" . $p_name . "\"/><br/><br/>";
echo "<label>Product Price *</label><br/>";
echo "<div><label style=\"font-style:italic\">(Without taxes)</label></div>";
echo "<input id=\"p_price" . $p_id . "\" class=\"text\" type=\"text\" name=\"p_price[]\" maxlength=\"6\" onkeypress=\"return currency(this, event)\" onchange=\"currency_format(this)\" onfocus=\"on_focus(this)\" onblur=\"on_blur(this)\" value=\"" . $p_price . "\"/><br/><br/><br/><br/>";
}
?>
<input class="button" type="button" value="Submit" onclick="product_edit_form_check()"/><br/><br/>
</form>
It would be helpful if you could post some of the HTML-part so we could see how you create your form. It seems you're generating your checkboxes without indexes in your array, so all checkboxes have the name/id "checkbox[]", which is ok if you don't care about the index, but if posted, the array will be numbered starting from "0" and then counting up which is the reason why you'll get "0" and "1" posted, even if "0" and "2" were checked.
Try to give your checkboxes' name/id numbers when generating the HTML, like "checkbox[0]", "checkbox[1]", "checkbox[2]", and so on. So when checkbox 0 and 2 are checked, you should get those values (including the correct index) posted.
The thing you have to bear in mind with HTML checkboxes is that they only POST a value if they are checked. If they are not checked, they don't get posted.
With this in mind, you should give each checkbox a name and then test for it in the POST to detect whether or not it has been passed back.
if (isset($_POST['MyCheckbox'])) {
} // else it wasn't checked!
Show us the HTML for the checkboxes.
Also, you have an SQL injection attack waiting to happen - a user can get any SQL they like onto the end of your query. Something like this illustrates what you should do with untrusted data:
//we're expect a number, so ensure we get one
$q_id = intval($_GET['q_id']);
//get into the habit of quoting query params,
//or better yet, use a wrapper library to help you
$sql="select * from products where q_id='".mysql_real_escape_string($q_id)."'";
If you declare checkbox name like (p_id[]), it's like telling PHP "I'm adding element to an array, enumerate it for me". Like in php $array[] = 't'; If you have several form elements with different names and you want to have synchronised IDs you HAVE to add index because otherwise browser will/may send only selected ones and PHP will enumerate it continuously.
You can specify indexes by using p_id[INDEX] and so on, where index is anything (I suggest numeric or alphanumeric).
Also, checkbox value can be altered and I encourage you to do it. value="1" helps, then you're sure that you get it.
<input type="checkbox" name="p_id[0]" value="1" />
In PHP you'll receive
$_POST['p_id'] ===> array(0 => 1);
et caetera.

Categories