multiple checkboxes used for search in php and mysql? - php

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%')

Related

Is there a way to have an adaptable prepared statement for an sql query

So i am trying to create a HTML front end that can use a text field to search an SQL Database. But there are multiple columns that can be searched, and many columns that contain numbers or letters. The User can search one or many of the columns at a time.
In my own test server, I've tried breaking down the possible queries into dropdown lists; and have switch cases to handle the selections. But this hasn't worked. My ultimate goal would be to have the textbox host all the query data, and have it passed to a prepared statement
So my question; is there a way to make a prepared statement adaptable, to handle single search cases or multiple search case. eg. WHERE column1 LIKE query1 (AND column2 LIKE query2).
Here's a basic concept, obviously you need to do your own validation and sanitizing etc. In your html use an array to hold all the form values:
<form action="#" method="post">
Col1:<br>
<input type="text" name="database[column1]"><br>
Col2:<br>
<input type="text" name="database[column2]"><br>
Col3:<br>
<input type="text" name="database[column3]"><br>
Then process that array to prepare a query
$input = $_POST['database']; // Assign all form variables to $input
$input = array_filter($input, 'strlen'); // Remove any form fields which were submitted with empty values
$where = implode(' AND ', (array_map(function($a){return "'$a' LIKE ?";}, array_keys($input)))); // Assemble your list of WHERE clauses
$statement = $dbo->prepare("SELECT * FROM table WHERE $where");
$statement->execute(array_values($input)); // Execute statement with corresponding variables
You can use this database query to get a list of columns for your table. Then using array_intersect_key you could filter out and column names which were submitted but did not exist in the table
SELECT column_name FROM information_schema.columns WHERE table_name='table';
This maybe long-winded and I am sure there are better approaches where you could loop it out or array. *Col1 text box must have data for this to work due to the "AND", I hope this helps.
<form action="#" method="post">
Col1:<br>
<input type="text" name="Col1"><br>
Col2:<br>
<input type="text" name="Col2"><br>
Col3:<br>
<input type="text" name="Col3"><br>
Col4:<br>
<input type="text" name="Col4"><br>
<input type="submit" name="search" value="Search"><br>
</form>
<br />
<br />
<?php
$SQL_Claus = "";
if (!empty($_POST['Col1'])){
$Col1 = $_POST['Col1'];
$SQL_Claus = $SQL_Claus . " Col1 LIKE " . $Col1;
}
if (!empty($_POST['Col2'])){
$Col2 = $_POST['Col2'];
$SQL_Claus = $SQL_Claus . " AND Col2 LIKE " . $Col2;
}
if (!empty($_POST['Col3'])){
$Col3 = $_POST['Col3'];
$SQL_Claus = $SQL_Claus . " AND Col3 LIKE " . $Col3;
}
if (!empty($_POST['Col4'])){
$Col4 = $_POST['Col4'];
$SQL_Claus = $SQL_Claus . " AND Col4 LIKE " . $Col4;
}
$SQL_Statement = "SELECT * FROM TABLE WHERE ".$SQL_Claus;
echo $SQL_Statement;
?>

What have I done wrong with my MySql query?

I'm trying to create a simple search function in PHP for my MySQL database. I've tried different tutuorials but I end up with the same result. From testing a bit with print_r I think the problem is the query, but I don't understand why it doesn't work. Does anyone have an idea? My code is following:
html
<form action="search.php" method="get">
<div class="input-field">
<input id="search" name="search" type="search" placeholder="Search lesson plans" required>
<label for="search"><i class="material-icons">search</i></label>
<i class="material-icons" id="closesearch">close</i>
</div>
</form>
php
<?php
require_once("db_link.inc.php");
if(isset($_GET['search'])) {
$search = $link->escape_string($_GET['search']);
$query = $link->query('SELECT * FROM LessonPlans WHERE Subject LIKE "%{$search}%" OR Level LIKE "%{$search}%" OR Aim LIKE "%{$search}%" AND Language="English"');
if($query->num_rows){
while($r = $query->fetch_object()){
echo '<div>
<p>'; $r->Subject; echo '</p>
</div>';
}
}
}
?>
Table
LessonPlans
Id | Subject | Level | Aim | Text | Language
Can anyone see what I've done wrong?
/HÃ¥kan
You did not print the $r->Subject inside your loop.
You did not properly concatenate the $search variable to your query
Your query should look like (if you insist on using single tick '):
$query = $link->query('SELECT * FROM LessonPlans WHERE Subject LIKE "%'.$search.'%" OR Level LIKE "%'.$search.'%" OR Aim LIKE "%'.$search.'%" AND Language="English"');
but if you want to keep on using the curly brackets:
$query = $link->query("SELECT * FROM LessonPlans WHERE Subject LIKE '%{$search}%' OR Level LIKE '%{$search}%' OR Aim LIKE '%{$search}%' AND Language='English'");
and for displaying/echoing the data:
echo '<div>
<p>'.$r->Subject.'</p>
</div>';
You can refer here for the difference of single tick (') and double tick (").

how to search array of checkboxes

Im building a search form but how do you search a array of checkboxes?
here is my html form
<form method="get">
<label>
<input type="checkbox" name="material[]" value="metal">metal
</label>
<label>
<input type="checkbox" name="material[]" value="plastic">Plastic
</label>
<label>
<input type="checkbox" name="material[]" value="carbon">Carbon
</label>
<input type="text" name="keyword">
<input type="submit" value="search">
</form>
and the php so far is. So how can i search the material for each checked.
<?php
if(isset($_GET['keyword'])){
$keyword = $_GET['keyword'];
// $material = $_GET['material'];
// $Search->search($keyword);
}
?>
ANd the query would be so far
$query = $this->pdo->prepare('SELECT * FROM `shop` WHERE `material` = ?');
When posted this will submit an array named material (accessible via $_GET['material']) that contains only the values that were checked.
You can then use those or output them like this:
foreach ($_GET['material'] AS $material) {
echo $material;
}
Addition after the question was edited:
You can also implode() the array values with ', ' as glue and use that as the search parameter in your SQL statement. Just change it to use IN instead of =, like #Prashant M Bhavsar suggested in his answer.
I think this will help you
Get your submitted material array in variable
$material_array = $_POST['material'];
You can implode array in select query to fetch related result
$selected_search_material = implode(',', $material_array);
SELECT * FROM `shop` WHERE `material` IN ($selected_search_material)
I haven't tested this yet, but since you receive an array ($_get['material'] is already an array), just use the following code with find_in_set;
<?php
$materials = array();
if (array_key_exists('material', $_GET)) {
$materials = $_GET['material'];
}
$query = $this->pdo->prepare('SELECT * FROM `shop` WHERE find_in_set(cast(material as char), :materials');
$query->execute(array('materials' => $materials));
?>
Implode $_GET['material'] and use a different query:
$where = implode(', ',$_GET['material']);
$query = $this->pdo->prepare('SELECT * FROM `shop` WHERE `material` IN ?');
Then use $where in your execute();
You can use $materialValue to store into Database.
<?php
if(isset($_GET['material'])){
$material = $_GET['material'];
foreach($material as $materialIndex){
$materialValue .= $materialIndex.',';
}
}
// use value to store into db
pass $materialValue variable to IN query also remove last "," from string
$materialValue.substring(0,$materialValue.length()-1);
?>

PHP foreach Construct Confusion

I am having a hard time wrapping my head around the foreach construct. I have found numerous examples of course, but I never seem to be able to adapt them to my needs.
Please consider this working example I have:
I am collecting two dates in an HTML form:
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" name="FirstAGMDate" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" name="MinutesInspectedFromDate" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
On submit the values are being pushed to the mysql database with a PDO prepared statement:
if (isset($_POST['submit'])) {
$sql = "UPDATE jobsinglevalues SET Date = :FirstAGMDate WHERE FormId = 0;
UPDATE jobsinglevalues SET Date = :MinutesInspectedFromDate WHERE FormId = 1;";
$sth = $db->prepare($sql);
$sth->execute(array(':FirstAGMDate'=>($_POST['FirstAGMDate']), ':MinutesInspectedFromDate'=>($_POST['MinutesInspectedFromDate'])));
}
This works no problem, but it's not very clever when I need to repeat this for a dozen inputs. What I want to do is achieve this with only one line of sql; looping for each <input type="text" name="Value" />.
How can I place this into a foreach loop?
In my head it works like this:
On submit each input updates the value in the database based on FormId, which increments by 1 each loop starting at 0. FormId is not a primary key, it simply mirrors the order in which the form elements are displayed.
Update - working example
if (isset($_POST['submit'])) {
$FormId = 0;
foreach($_POST['Value'] as $avalue){
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId";
$sth = $db->prepare($sql);
$sth->execute(array(':Value'=>($avalue), ':FormId'=>($FormId)));
++$FormId;
}
}
This seems to logically work to me! Is the correct solution similar? Please let me know if I need to clarify anything.
Thankyou,
Sam
Let's start by making sure all our values are in an array after posted; if you don't care about the keys you can just use name="Values[]", but I'll use name="Value[FirstAGMDate]" etc so we know what key a value belongs to.
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" id="FirstAGMDate" name="Value[FirstAGMDate]" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" id="MinutesInspectedFromDate" name="Value[MinutesInspectedFromDate]" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
Now we can process the posted array of values. If we want to do something with the key, we can use foreach($_POST['Value'] as $akey => $avalue), if we are only interested in the values then foreach($_POST['Value'] as $avalue) suffices.
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId;";
$sth = $db->prepare($sql);
foreach($_POST['Value'] as $akey => $avalue) {
$sth->execute(array(':Value' => $avalue, ':FormId'=> $FormId ));
++$FormId;
}
[edit] As per edit-suggestion by #AravindKishore, creating the prepared statement is better done before the loop. Prepare once, enjoy forever.

Using jQuery serialize to put ajax values into a database select query

I have the following code:
<?php
$allform = $_POST['allform'];
parse_str($allform, $output);
$allquery = "SELECT * FROM wp_users";
$names = array();
$allresult = mysql_query($allquery) or die(mysql_error()); ?>
...
<?php
while ($rows = mysql_fetch_array($allresult)) {
$names[] = $rows['user_email'];
}
?>
The allform variable is a jQuery serialize string:
var allform = $('form#all').serialize();
Basically, I want to put the values from the form in the front end into a mysql select query in the back end.
The form is a bunch of checkboxes so the idea is that the SELECT something will have different number of values depending on what the user checks. Any ideas?
Thanks
The best thing to do could be something like this. Your checkboxes should be like this
<input type="checkbox" name="checkboxes[]" value="cream" />
<input type="checkbox" name="checkboxes[]" value="choco" />
<input type="checkbox" name="checkboxes[]" value="lime" />
server side you receive an array
$flavours = $_POST["checkboxes"];
$sql = "SELECT ".implode(',', $flavours)." FROM FLAVOURTABLE";

Categories