This question already has an answer here:
Building an SQL query based on checkboxes
(1 answer)
Closed 8 years ago.
I want to build a query form my database depending my checkboxes list.
My checkboxes:
<input type="checkbox" id="searchName" checked> Name
<input type="checkbox" id="searchAddress"> Address
<input type="checkbox" id="searchCompany"> Company
<input type="checkbox" id="searchComments"> Comments
My PHP:
$subQuery='';
if($_POST['searchName']=='true') { $subQuery .= " AND KDX_Name LIKE :KDX_SearchTerm"; }
if($_POST['searchAddress']=='true') { $subQuery .= " OR KDX_PostalAddress LIKE :KDX_SearchTerm"; }
if($_POST['searchCompany']=='true') { $subQuery .= " OR KDX_Company LIKE :KDX_SearchTerm"; }
if($_POST['searchComments']=='true') { $subQuery .= " OR KDX_Comments LIKE :KDX_SearchTerm"; }
My problem:
If the first checkbox is not checked, my query is not working cause it works with OR whereas it must start with AND.
Could you please help ?
Thanks.
You have many mistakes in your code in HTML and in PHP ...
I'll not mention everything here, but this is how I would do this.
<input type="checkbox" name="searchName" checked="checked" />Name
<input type="checkbox" name="searchAddress" />Address
<input type="checkbox" name="searchCompany" />Company
<input type="checkbox" name="searchComments" />Comments
<?php
$fields = array(
'searchName' => 'KDX_Name',
'searchAddress' => 'KDX_PostalAddress',
'searchCompany' => 'KDX_Company',
'searchComments'=> 'KDX_Comments',
);
$cond = array();
foreach ($fields as $form_field => $db_field) {
if (isset($_POST[$form_field])) {
$cond[] = "$db_field LIKE '%'" . mysql_escape($_POST[$form_field]) . "%'";
}
}
$subQuery = implode(' OR ', $cond);
?>
More important are these things:
correct HTML form (not id, but name),
easy to extend PHP (use array for field names),
don't check for $_POST[foo]=='true' which is absolutely wrong,
add conditions in array and at the end use implode to easily concatenate everything together,
escape user input variables to avoid SQL injection attacks.
Related
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 table with 7 columns populated from mysql... the table headers each contain a checkbox which if checked and clicked on submit will be sent to a export to csv page.
Is there a way to use the SELECT $var1, $var2...$var7 FROM... ? $var1 to $var7 will be used if checkbox checked and if no checkbox checked then display some message
To betted understand what i am asking i'll put some code...
HTML
<td class="captabel">
<input type="checkbox" value="expid" >
</td>
<td class="captabel">
<input type="checkbox" value="exploc" >
</td>
etc
php
if(isset($_POST['expid'])){
$expid="id";
}
else{
$expid="";
}
if(isset($_POST['exploc'])){
$exploc="locatie";
}
else{
$exploc="";
}
etc
and at some point comes the SELECT * FROM table... <-- this is what i want to replace with SELECT $expid, $exploc ... FROM table...
i have tried various ways and none worked.
Thanks.
You have to use the name attribute on your checkbox
<input type="checkbox" value="123" name="expid" />
Modify your input type <input type="checkbox" name="exploc" value="exploc">
In your php script check :
$selectStr= "";
if(!empty($_POST['expid'])) {
$selectStr="id";
}
else{
$selectStr="";
}
if(!empty($_POST['exploc'])) {
$selectStr= !empty($selectStr) ? ", locatie" : "locatie";
}
else{
$selectStr="";
}
so your query will be
if(!empty($selectStr)) {
$qry = "SELECT $selectStr FROM table...";
}
Instead of setting different name you can set array type name in <input type="checkbox" value="exploc" name="exploc[]">
Solved it.
Based on Dipanwita Kundu answer i used
if(!empty($columns)){
$sql = 'SELECT '. implode(', ', $columns). ' FROM raport' ;
}
and works like a charm.
Thank you.
This seems to be a common question as I have seen plenty of similar questions.
however, none of the answers actually pointing out how to do the selecting from mysql database and this is my issue as the moment.
basically I have a table which I store the search data in it.
it looks like this:
id blond darkHair busty curvy
---------------------------------------------------
1 blond busty
2 dark hair busty curvy
3 blond curvy
4 blond curvy
and I have a form with checkboxes like so:
<form action="search.php" method="post">
<input name="keyword[]" type="checkbox" value="blond" />
<input name="keyword[]" type="checkbox" value="dark hair" />
<input name="keyword[]" type="checkbox" value="busty" />
<input name="keyword[]" type="checkbox" value="curvy" />
</form>
and the PHP codes like this:
if(isset($_POST['keyword']))
{
$keyword = $_POST['keyword'];
foreach ($_POST['keyword'] as $keyword) {
$keywordarray[] = mysqli_real_escape_string($conx, $keyword);
}
$keywords = implode (",", $keywordarray);
$sql = "SELECT * FROM girlsStaff
WHERE (`blond` LIKE '%".$keyword."%') OR (`darkHair` LIKE '%".$keyword."%') OR (`busty` LIKE '%".$keyword."%') OR (`thin` LIKE '%".$keyword."%')" or die();
$query = mysqli_query($conx, $sql);
Now, apart from converting this code to PDO or prepared statement, there is another issue which I don't understand!
it doesn't matter how many chechboxes i select... it always returns the result for last checked/selected checkbox value from mysql database....
is there something that I am missing?
i also, did echo $keywords at the top of my page to see whats being sent to the page and I get the value of all the selected/checked boxes being sent correctly.. so I know the issue is not there.
any help or advice would be appreciated.
You require to build query dynamically.
<?php
$clause = " WHERE ";//Initial clause
$sql="SELECT * FROM `girlsStaff` ";//Query stub
if(isset($_POST['submit'])){
if(isset($_POST['keyword'])){
foreach($_POST['keyword'] as $c){
if(!empty($c)){
$sql .= $clause."`".$c."` LIKE '%{$c}%'";
$clause = " OR ";//Change to OR after 1st WHERE
}
}
}
echo $sql;//Remove after testing
}
?>
<form method="POST" action="#">
<form action="search.php" method="post">
Blond: <input name="keyword[]" type="checkbox" value="blond" />
Dark Hair: <input name="keyword[]" type="checkbox" value="dark hair" />
Busty : <input name="keyword[]" type="checkbox" value="busty" />
Curvy; <input name="keyword[]" type="checkbox" value="curvy" />
<input type="submit" name="submit" value="Submit">
</form>
Sample queries
2 check boxes filled
SELECT * FROM `girlsStaff` WHERE `dark hair` LIKE '%dark hair%' OR `curvy` LIKE '%curvy%'
4 filled
SELECT * FROM `girlsStaff` WHERE `blond` LIKE '%blond%' OR `dark hair` LIKE '%dark hair%' OR `busty` LIKE '%busty%' OR `curvy` LIKE '%curvy%'
I think that small change from $keyword to $keywords will solve your problem :)
Now you are looking for items like your last value from $_POST['keyword'] array.
This line:
$sql = "SELECT * FROM girlsStaff WHERE (`blond` LIKE '%".$keyword."%') OR (`darkHair` LIKE '%".$keyword."%') OR (`busty` LIKE '%".$keyword."%') OR (`thin` LIKE '%".$keyword."%')" or die();
You should also use IN instead of LIKE if you have list aaa, bbb, ccc...., but then you will look for elements that have exactly same string in those fields.
After change to $keywords you will have:
... WHERE (`blond` LIKE '%".$keywords."%')
will also not work due to it will mean:
... WHERE (`blond` LIKE '%aaa,bbb,ccc%')
If you want to use like (if fields in DB only contain strings from array) then I suggest to build your query in foreach loop. Example:
$sql = "SELECT * FROM girlsStaff WHERE ".
foreach ($_POST['keyword'] as $keyword) {
$sql .= "(`blond` LIKE '%".$keyword."%') OR ";
}
//and here cut last four character " OR " part that will be unusefull
Typos:
$keywords = implode (",", $keywordarray);
^--- with an S
WHERE (`blond` LIKE '%".$keyword."%')
^--- without an S
You're stuffing in your original $_POST['keyword'] array. An array in string context is the literal word Array, so your query is actually executing as
WHERE (`blond` LIKE '%Array%')
I want to Filter from MyTable
the way I get as result only the rows corresponding to the checkboxes checked.
(1) <input type="cBox" name="Filter[Table_Column_Name_X]" value="y" />
(2) <input type="cBox" name="Filter[Table_Column_Name_Y]" value="y" />
(3) <input type="cBox" name="Filter[Table_Column_Name_Z]" value="y" />
Ex.:
if 'only' checkbox (1) is checked
I retrieve 'only' the rows WHERE Table_Column_Name_X='y'
if checkbox (1) and if checkbox (3) are checked
I retrieve 'only' the rows WHERE Table_Column_Name_X='y' AND Table_Column_Name_Z='y'
.........and so on foreach checkbox checked!
Something like this
if(isset($_POST['Filter'][]) && !empty($_POST['Filter'][]){
$query= "Select * From MyTable WHERE Table_Columns_Names_Checked='y'";
}
Myabe I should use variables or foreach statement. Any help appreciated.
Your HTML code is incorrect:
<input type="checkbox" name="Filter[]" value="Table_Column_Name_X" />
<input type="checkbox" name="Filter[]" value="Table_Column_Name_Y" />
<input type="checkbox" name="Filter[]" value="Table_Column_Name_Z" />
Your PHP code (following code is untested):
$where = "";
if(isset($_POST['Filter'] ) {
foreach( $_POST['Filter'] as $filter ) {
switch( $filter ) {
case 'Table_Column_Name_X' : if( $where != '' ) $where .= " AND ";
$where .= Table_Column_Name_X = ??????????;
break;
//--- repeat above for other 2 options
}
$sql = "Select * From MyTable";
if( $where != "" ) $sql .= " WHERE " . $where;
//--- do the query
The ????? indicates that the column must have a particular value for the query to work on otherwise it will just return everything and there is no need for the filter.
It is not wise to use table/fieldnames in your HTML as you are exposing the structure of you database to would be hackers. Use numbers instead.
I was wondering if you could tell me what is wrong with my code or point out where I am going wrong, as I am not able to display any results. $_POST['checkbox'] is an array.
<?
$get_id=$_POST['checkbox'];
if(empty($get_id)) {
echo("<h3>You didn't select anything.</h3>");
} else {
$where[] = sprintf(" id='%s'",$_POST["checkbox"]);
}
$where_str = " WHERE ".implode(" AND ",$where);
$sql = "SELECT * FROM products $where_str";
$result = mysql_query($sql, $link);
echo "<table>";
echo "<tr> <th>Description</th> </tr>";
while($row = mysql_fetch_array($result)) {
echo "<tr><td>";
echo $row['description'];
echo "</td></tr>";
}
echo "</table>";
?>
You should refrain from using short tags <? as they are not supported after PHP 5.4.
You are not connecting to MySQL ($link undefined)
You are using a deprecated API (mysql_). See comments for alternatives (mysqli_ or PDO)
You should use the REQUEST_METHOD index of $_SERVER to determine whether your script has been posted.
if( $_SERVER[REQUESTED_METHOD] == 'POST' && !empty($_POST['checkbox']) ) {
... }
You need to use error handling to check for errors. If you echo $sql; you would see that the checkboxes aren't being populated:
SELECT * FROM products WHERE id=''
Your script is vulnerable to SQL injection. When you switch to current API, use binded parameters.
Is $_POST[checkbox] an array?
sprintf will not work as you intend it to because you are passing the entire $_POST[checkbox] array to it. You would need to iterate through it to format it. (See Ollie's answer)
Example
Assuming your HTML looks like this:
<form method="post" ...>
<input type="checkbox" name="checkbox[]" value="1" />
<input type="checkbox" name="checkbox[]" value="2" />
<input type="checkbox" name="checkbox[]" value="3" />
<input type="submit" name="submit" />
</form>
And all three boxes are checked; it will produce this array:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Following Collie's loop:
foreach ($_POST['checkbox'] as $checkbox) {
$where[] = sprintf(" id='%s'",$checkbox);
}
$where will look like:
Array
(
[0] => id='1'
[1] => id='2'
[2] => id='3'
)
The rest of your script should work. However, you should look into using the IN operator.
That will enable you to skip the loop and just use implode:
$where = "'" . implode("', '", $_POST[checkbox]) . "'";
Which produces:
'1', '2', '3'
And combined with IN:
$sql = "SELECT ... FROM WHERE id IN ($where)";
Be aware that this is not sanitized and you're still vulnerable to injection.
If $_POST["checkbox"] is an array like you say then you cannot use it as a string in the sprintf. Try using array_pop to return the last value of that array or similar.
You could foreach through each element in the array:
foreach ($_POST['checkbox'] as $checkbox) {
$where[] = sprintf(" id='%s'",$checkbox);
}
Although this will probably just create an invalid SQL statement if asking for ID to be equal to two different integers.