Problem statement:
I have a form with multiple checkbox Fields, i have validated it so
user can select maximum 9 checkbox and atleast 1 with jquery.
I collect the Form checked values using Post method.
i have mysql table with 12 columns.
first 3 columns are "id", "rollnum", "selectStatus"
Through session variables created during Login, i get roll number of student. So i can Run Update Query on particular row.
Question: How do i Update those 9 subject columns according to user checked inputs. Note : i stored those checked input field values in an array.
Code
<form action="index.php" id="form-3" method="post">
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="ucs303">UCS303 Operating Systems
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="ucs406">UCS406 Data Structures and Algorithms
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="uec401">UEC401 Analog Communication Systems
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="uec612">UEC612 Digital System Design
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="uec307">UEC307 Electromagnetic Field Theory & Trans Lines
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="uec502">UEC502 Digital Signal Processing
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="uec510">UEC510 Computer Architecture
<button type="submit" name="year-3-submit">Submit Selection</button>
</form>
<?php
if(isset($_POST['year-3-submit'])){
if(!empty($_POST['year-3-checkbox'])){
$subjectCheckList = array();
$subjectCheckList = $_POST['year-3-checkbox'];
}
}
?>
It depends on user how many checkbox is selected.
I donot know how to write UPDATE sql query which updates values of number of columns == size of array.
for example:
User 1 has selected 3 checkbox and submitted form, we have array of size 3 and UPDATE 3 columns of table.
User 1 has selected 6 checkbox and submitted form, we have array of size 6 and UPDATE 6 columns of table.
I donot want to write 9 switch case statements for all possible sizes
of array. Any idea? please?
Based on OP's comments, you can make the code generic as follows:
// Check if atleast one subject has been selected
$selectedSubjects = array_filter($subjectCheckList);
// If no subject selected
if (empty($selectedSubjects)) {
$sql = "UPDATE subjectmaster
SET substatus = 0
WHERE rollno = '" . mysqli_real_escape_string($rollnumber) . "'";
} else {
// Initialize the sql string
$sql = "UPDATE subjectmaster
SET substatus = 1 ";
$i = 1;
foreach ($subjectCheckList as $subject) {
$sql .= ", sub" . $i . " = '" . mysqli_real_escape_string($subject) . "' ";
}
$sql .= " WHERE rollno = '" . mysqli_real_escape_string($rollnumber) . "'";
}
Also, note the use of mysqli_real_escape_string. It helps in preventing SQL injection. For better ways to prevent SQL injection, you may check How can I prevent SQL injection in PHP?
Well, 1st of all it is not clear what should be the default valued for each column.
Since your MySQL columns are set by numbers (sub1, sub2, etc) then your form should represent them accordingly, with the proper value. for example:
<input class="form-check-input" name="year-3-checkbox[]" type="checkbox" value="1">
This way, you can loop easily and update the table (I assume the sub columns are TINYINT(1) DEFAULT NULL) :
<?php
if(isset($_POST['year-3-submit'])){
if(!empty($_POST['year-3-checkbox'])){
$subjectCheckList = array();
$query = "UPDATE table SET ";
foreach ($_POST['year-3-checkbox'] as $key => $value) {
$query .= " sub" . $value . " = 1, "
}
$query = substr($query, 0, -1);
}
}
?>
Hope this helps
Guy
You can also use array_filter, array_combine and array_slice.
<?php
$subs = [':sub1',
':sub2',
':sub3',
':sub4',
':sub5',
':sub6',
':sub7',
':sub8',
':sub9'
];
// use $dataFromForm = array_filter($_POST['year-3-checkbox'])
$dataFromForm = ['11111',
'222222',
'3333333'];
$dbh = new PDO('mysql:host=localhost;dbname=test', 'root', '*******');
$sql = 'UPDATE test SET sub1 = :sub1, sub2 = :sub2, sub3 = :sub3, sub4 = :sub4, sub5 = :sub5, sub6 = :sub6, sub7 = :sub7, sub8 = :sub8, sub9 = :sub9';
$sth = $dbh->prepare($sql);
$sth->execute(array_combine(array_slice($subs, 0, count($dataFromForm), $dataFromForm)));
I have a control panel in php and mysql that displays on page load. I have a checkbox on that page(default off, not stored in db or tied to anything other than being an option to show old items), that when i click it, i want the query to refresh the data with the new filter applied. Basically on load it show only active items, when they check the checkbox i want the page to reload showing outdated items.
My code is:
<form action="" method="POST">
<input type="checkbox" name="filter" value="true">
</form>
<?PHP
$showold = (isset($_REQUEST['filter']));
if ($showold === 'checked' )
{
$showold = "WHERE `MyTable` = '0'";
}
else
{
$showold = "WHERE `MyTable` = '1'";
}
$query_NowPouring = "SELECT * FROM MyTable $showold";
$result = mysqli_query($mysqli, $query_NowPouring);
if($result){
while($row = mysqli_fetch_array($result)){
#set variables here and display the info in table here.
}
}
?>
Your code (isset($_REQUEST['filter'])); is returning boolean like 0 or 1 not string and you are matching it with string at if ($showold === 'checked' ) .
Problem is you can not compare boolean with string.
I have a form which has select options for age and radiobuttons for gender. The idea is that the form can be used to search for a specific user by age and gender.
Currently, the form sometimes executes the header (see below) and sometimes not. So Assume, I am logged in as Conor, Conor specifies that he wants to search for a user aged between 20-21 and is male. Upon clicking submit, sometimes the form will find someone, sometimes it will not. I want the query to keep running until a user is found, unless no one exists in the database.
In this case, the header should be executed, taking the user to messages.php because a male aged 20 exists in the database.
Here is my approach:
Form:
<form action="random_chat.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="age_from" id="age_from" value="0"/>
<input type="hidden" name="age_to" id="age_to" value="50"/>
<label for="amount">Age:</label>
from:
<select name="age_from" id="age_a" onchange="checkages_a()">
<option value="none"></option>
<?php
for($i = 17; $i <= 50; ++$i) {
echo "\t", '<option value="', $i. '">', $i, '</option>', "\n";
}
?>
</select>
to:
<select name="age_to" id="age_b" onchange="checkages_b()">
<option value="none"></option>
<?php
for($i = 18; $i <= 50; ++$i) {
echo "\t", '<option value="', $i, '">', $i, '</option>', "\n";
}
?>
</select>
<!-- I have input type submit above the radio buttons due to table layout -->
<input type="submit" class="btn btn-info" name="submit" value="Click to start chat! " />
<label for="amount">Gender:</label>
<input type="radio" name="gender" value="male">Male</input> <br />
<input type="radio" name="gender" value="female">Female</input><br />
<input type="radio" name="gender" value="any">Any</input>
</form>
PHP code processing the form:
<?php
$refined_gender = htmlentities (strip_tags(#$_POST['gender']));
$age_from = htmlentities (strip_tags(#$_POST['age_from']));
$age_to = htmlentities (strip_tags(#$_POST['age_to']));
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
if (isset($_POST['submit'])){
// if age parameter used...
$defined_chat = mysqli_prepare ($connect, "SELECT * FROM users WHERE gender =? AND age BETWEEN ? AND ? ORDER BY RAND() LIMIT 1");
mysqli_stmt_bind_param($defined_chat, "sss", $refined_gender, $age_from, $age_to);
mysqli_stmt_execute ($defined_chat);
while ($get_user = mysqli_fetch_assoc($defined_chat)){
$rand_name = $get_user['username'];
$acc_type = $get_user['account_type'];
if ($acc_type != "admin" ){
// if the name genereated by db is same as logged in users name, then run query again until name is found.
if ($rand_name == $username){
$defined_chat;
} else {
header ("Location: /messages.php?u=$rand_name");
}
} else {
echo "No user found fitting those requirements.";
}
} // while closed
mysqli_stmt_close($defined_chat);
}
?>
I have tried to change the form action to '#', thinking it may be just be refreshing the page, but it didn't work.
Also, how can I make this so that even if one parameter is filled, then still execute search? For example, if I search for a male, with no age defined, it will find a male user. If I search for someone ages between 26-31 and no gender defined, then still execute header?
Edit:
$username is the session variable, which is defined at the very start of random_chat.php.
Do not rely on the value of a submit button to determine if your form was submitted or not. This will not work on all browsers, especially older ones, this value is not always passed back to the server, instead just look at any value inside the form to verify if submission has occurred, or the existence of $_POST in general.
At first sight, what you are attending to do looks to me simpler than the way you are actually trying to achieve it.
Construction you SQL query correctly may be the only thing complicated in here.
Only changing your query could actually already remove your need of the if/else for the account_type and the if/else to check if the current user is the same as the queried one :
$sql = "SELECT
*
FROM
users
WHERE
gender like ? AND
age BETWEEN ? AND ? AND
# with this condition you do not need to test if the user logged is the queried one
username != ? AND
# and with this one, you do not care about exclude adimn either
account_type != 'admin'
ORDER BY RAND()
LIMIT 1";
$defined_chat = mysqli_prepare (
$connect, $sql
);
mysqli_stmt_bind_param(
$defined_chat,
"ssss",
$refined_gender,
$age_from,
$age_to,
$username
);
Then about the fact that you want to be able to search even without any selection on both gender and age, you can use a combinaison of the wildcard % of SQL, the operator like and the ternary operator of PHP (you did maybe already see that I changed gender =? to gender like ? in the query above).
// Means if gender is different than 'any', it will assign the posted value to the variable, otherwise, it will assign the sql wildcard %
$refined_gender = (htmlentities (strip_tags(#$_POST['gender'])) != 'any' ? htmlentities (strip_tags(#$_POST['gender'])) : '%');
// Means if age is different than 'none', it will assign the posted value to the variable, otherwise, it will assign the lowest possible age, 0
$age_from = (htmlentities (strip_tags(#$_POST['age_from'])) != 'none' ? htmlentities (strip_tags(#$_POST['age_from'])) : '0');
// Means if age is different than 'none', it will assign the posted value to the variable, otherwise, it will assign an age bigger than anyone could attain, 9999
$age_to = (htmlentities (strip_tags(#$_POST['age_to'])) != 'none' ? htmlentities (strip_tags(#$_POST['age_to'])) : '9999');
see ternary operators in PHP doc
and see MySQL like and wildcard usage
All in one, your processing PHP script could look like this :
$refined_gender = (htmlentities (strip_tags(#$_POST['gender'])) != 'any' ? htmlentities (strip_tags(#$_POST['gender'])) : '%');
$age_from = (htmlentities (strip_tags(#$_POST['age_from'])) != 'none' ? htmlentities (strip_tags(#$_POST['age_from'])) : '0');
$age_to = (htmlentities (strip_tags(#$_POST['age_to'])) != 'none' ? htmlentities (strip_tags(#$_POST['age_to'])) : '9999');
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
if (isset($_POST['submit'])){
$sql = "SELECT
*
FROM
users
WHERE
gender like ? AND
age BETWEEN ? AND ? AND
# with this condition you do not need to test if the user logged is the queried one
username != ? AND
# and with this one, you do not care about exclude adimn either
account_type != 'admin'
ORDER BY RAND()
LIMIT 1";
$defined_chat = mysqli_prepare (
$connect, $sql
);
mysqli_stmt_bind_param(
$defined_chat,
"ssss",
$refined_gender,
$age_from,
$age_to,
$username
);
mysqli_stmt_execute ($defined_chat);
while ($get_user = mysqli_fetch_assoc($defined_chat)){
$rand_name = $get_user['username'];
header ("Location: /messages.php?u=$rand_name");
} // while closed
echo "No user found fitting those requirements.";
mysqli_stmt_close($defined_chat);
}
You have some mixed logic, so some explanations might help.
1) header('location: ...') will tell the browser to reload the page to the new location. This does not appear to be what you want - you just want to continue execution? NOTE: You should also [nearly] always have "exit();" after a header('location: ... '); line otherwise execution continues which is [nearly] never what you want!)
2) a while loop will continue "while" the condition is true. So the loop continues while there are rows being returned.
3) Running the query again will not return anything new - you can use the same results. So just skip over until you find the result you need!
So, written in English, what you want to do after running the DB query is:
set a tally count to zero
while we have some rows coming from the db {
if that row is not admin {
if that row does not match the current user {
show the result
increase tally count
}
}
}
if tally count is zero {
say "no entries found"
}
So, in code, this is
$foundUsers = 0;
while ($get_user = mysqli_fetch_assoc($defined_chat)){
$rand_name = $get_user['username'];
$acc_type = $get_user['account_type'];
if ($acc_type !== "admin" ){
// if the name genereated by db is same as logged in users name, then run query again until name is found.
if ($rand_name !== $username) {
$foundUsers = $foundUsers + 1; // Or $foundUsers++ for short
echo 'Matched User: ' . $rand_name . '<br>';
}
}
} // while closed
if ($foundUsers == 0) {
echo "No user found fitting those requirements.";
}
Ok, first of all, if you want to exclude a parameter from the query, you're going to have to build some logic to exclude that variable.
So if $refined_gender = "any", then you need to exclude it from the query. I would change your combobox default values to:
<select name="age_from" id="age_a" onchange="checkages_a()">
<option value="-1"></option>
<?php
for($i = 17; $i <= 50; ++$i) {
echo "\t", '<option value="', $i. '">', $i, '</option>', "\n";
}
?>
</select>
to:
<select name="age_to" id="age_b" onchange="checkages_b()">
<option value="999"></option>
<?php
for($i = 18; $i <= 50; ++$i) {
echo "\t", '<option value="', $i, '">', $i, '</option>', "\n";
}
?>
</select>
Then, now you've fixed the age between, to filter the gender out. Also, I've added a clause to your WHERE clause: AND account_type != 'admin', this will filter out the admins accounts on the SQL side rather than checking on the PHP side.
// If gender is specified, query gender
if($refined_gender !== "any"){
$defined_chat = mysqli_prepare ($connect, "SELECT * FROM users WHERE gender =? AND age BETWEEN ? AND ? AND account_type != 'admin' ORDER BY RAND() LIMIT 1");
mysqli_stmt_bind_param($defined_chat, "sii", $refined_gender, $age_from, $age_to);
} else {
$defined_chat = mysqli_prepare ($connect, "SELECT * FROM users WHERE age BETWEEN ? AND ? AND account_type != 'admin' ORDER BY RAND() LIMIT 1");
mysqli_stmt_bind_param($defined_chat, "ii", $age_from, $age_to);
}
mysqli_stmt_execute ($defined_chat);
Suggestion #1: Possible race condition see note in code.
if ($acc_type != "admin" ){
// if the name genereated by db is same as logged in users name, then run query again until name is found.
if ($rand_name == $username){
$defined_chat;<-- don't you need to re-execute this? Seems like you are hitting a race condition since the statement result will never change
} else {
header ("Location: /messages.php?u=$rand_name");
}
} else {
echo "No user found fitting those requirements.";
}
Suggestion #2:
Outside of that you should be sure you aren't getting the current user with a
WHERE name NOT LIKE '%?%' up front in the initial query and get rid of that if statement.
Suggestion #3:
Or better, use the user IDs. What if there's another user with the same name as the searcher, but they're a different person? Base the current user match on UID, not name.
Suggestion #4:
You should absolutely almost never run a select query/statment inside a PHP (or any scripting language) loop. There's always a better way. Filter your data in the database where it's efficient. Even for inserts you can do a single bulk insert much more efficiently than a bunch of insert queries.
I am totally stuck here and found tens of samples on posting to get and set values. What I am trying to do is -
Let a user enter a vehicles year model into a textbox in my form (set to post)
I then need to get this value to a variable state
$vehicle_year = $_GET['vyear'];
First error is here... vyear is the name and id for my textbox. Error - Undefined index 'vyear'. There is no submission of the form etc, because I am still on the same form/page.
With this value captured, I then search my database to return all of the manufacturers that has a year (as returned) attached to it -
$query = "SELECT * FROM `vehicledata` WHERE `year`='$vehicle_year'";
Obviously it does not work because I still do not have the value as yet returned from above with the undefined error. I've tried to change the name and id of the textbox, no luck.
Once these records has been returned, I need to add the values to a select (drop down) box. I have no idea how to get the values in there - seems I need to run a loop, which I know how to, just don't know how to add the options to the select box.
Please note that my form is NOT submitted, I need to load all the relevant data first before it gets submitted.
Any help will be appreciated, thanx guys.
P.S. I will add against sql injection once I know how to get the values and add the options. Just need the basics to get me going.
HTML:
//This would be my code...
Search Just my Wheels
Year
<?php
$vehicle_year = isset($_POST['vehicleyear']) ? $_POST['vehicleyear'] : -1;
if ($vehicle_year == -1) {
echo 'No Value Returned...';
//returns no value...
} else {
//How to get the value and echo it out...
echo $vehicle_year;
}
//$query = "SELECT * FROM (SELECT * FROM `vehicledata` WHERE `year`='$vehicle_year' ORDER BY `cid` DESC LIMIT 1, 10) AS `table` ORDER BY `cid` ASC";
$query = "SELECT * FROM `vehicledata` WHERE `year`='$vehicle_year'";
$result = mysql_query($query);
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
$vehicle_id = $line['cid'];
$vehicle_year = $line['year'];
$manufacturer = $line['carfindmake'];
//Get manufacturer data...
$images = get_make($vehicle_year);
if (!empty($make)) {
echo 'No data';
} else {
echo 'Found stuff';
}
}
?>
<td align="right"><span style="visibility:hidden" id="makelabel"><strong>Make</strong> </span></td>
<!--<td><input name="make" id="make" type="text" class="searchbox" style="visibility:hidden" onClick="toggleVisibility('modellabel'); toggleVisibility('model');"/></td>-->
<td><select name="make" id="make" class="searchbox" style="visibility:hidden" onClick="toggleVisibility('modellabel'); toggleVisibility('model');"/></td>
2) This is causing an error when your form has not yet been submitted because the value is not set.
Fix this by the following:
$vehicle_year = '';
if ( isset( $_POST['vyear'] ) ) {
$vehicle_year = $_POST['vyear'];
}
1 - If the form is set to POST, you've got to use $_POST["vyear"] to recover the value.
2 - Double check the case of the textbox's name.
my form (set to post)
$vehicle_year = $_GET['vyear'];
If your form is set to use POST, you'll need to access the form elements through the $_POST superglobal as such:
$vehicle_year = $_POST['vyear'];
If you're having issues because an index may or may not be set, use PHP's isset() to check. If the index isn't set, it won't cause an error.
if(isset($_POST['vyear'])) {
$vehicle_year = $_POST['vyear'];
}
I am trying to pass a selected checkbox value from one page to another to run a mysql statement on my db.
This is what I have:
HTML
<form method='POST' action='move_compaudit.php'>
<input type='hidden' name='checkbox' value='0'/>
<input type='checkbox' name='checkbox' value='1'/>
PHP (this file called move_compaudit.php)
<?php
include('include/dbConnection.php');
$checkbox = isset($_POST['checkbox']) ? 'Set' : 'NotSet';
//SQL statement
$query = "SELECT * FROM compaudit;";
$results = mysqli_query($dbc,$query) or die('Error querying database');
$row = mysqli_fetch_array($results);
$query1 = "DELETE FROM compaudit WHERE serial_no = $row[7] AND $checkbox = 'Set'";
//Execute prepared MySQL statement
//$results1 = mysqli_query($dbc,$query1) or die('Error querying database');
print_r($query);
print_r($query1);
?>
My badly printed query: I get this everytime, regardless of click or not clicked.
SELECT * FROM compaudit;DELETE FROM compaudit WHERE serial_no = 12345 AND Set = 'Set'
If you are going to keep your HTML as it is, you need to check the actual value of $_POST['checkbox'] instead of checking if it is set. Your hidden field guarantees that even if it is not checked, $_POST will still get a value for "checkbox".
<?php
include('include/dbConnection.php');
$checkbox = ($_POST['checkbox'] == '1') ? 'Set' : 'NotSet';
....
Set is keyword in mysql :) you should escape it with `
If you declare before the checkbox a hidden with same name, this variable will be forever true for isset.
Look to #GameBit tip, escape with backticks the fields and quote/escape all variables before use into a query.