PHP MySQL search with multiple criteria - php

I have a search form in a website and would like to have several search terms which is input by the user to perform db search, terms as below:
Keywords
Property For (Sale, Rent...)
Property Type (Apartment, Terrace House...)
State
Min Price
Max Price
Here is script to perform search with above term's input
public function get_property_list_by_search($start, $per_page, $keyword, $prop_for, $min, $state, $ptype, $max, $mysqli)
{
if(empty($start) && empty($per_page))
{
return 0;
}
$start = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($start));
$per_page = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($per_page));
$keyword = $mysqli->real_escape_string(stripslashes($keyword));
$prop_for = $mysqli->real_escape_string(stripslashes($prop_for));
$state = $mysqli->real_escape_string(stripslashes($state));
$ptype = $mysqli->real_escape_string(stripslashes($ptype));
$min_price = self::num_clean($mysqli->real_escape_string($min));
$max_price = self::num_clean($mysqli->real_escape_string($max));
$t1 = '';
$t2 = '';
$t3 = '';
$t4 = '';
$t5 = '';
if(isset($keyword) && !empty($keyword)){
$t1 = " AND `proj_title` LIKE '%".$keyword."%' OR `proj_addr` LIKE '%".$keyword."%' OR `proj_area` LIKE '%".$keyword."%'";
}
if(isset($prop_for) && !empty($prop_for)){
$t2 = " AND `proj_for`='".$prop_for."'";
}
if(isset($state) && !empty($state)){
$t3 = " AND `state`='".$state."'";
}
if(isset($ptype) && !empty($ptype)){
$t4 = " AND `proj_cat`='".$ptype."'";
}
//min & max
if((isset($min_price) && !empty($min_price)) && (isset($max_price) && !empty($max_price))){
$t5 = " AND `price` BETWEEN '".$min_price."' AND '".$max_price."'";
}
//min only
if(!empty($min_price) && empty($max_price)){
$t5 = " AND `price` >= '".$min_price."'";
}
//max only
if(empty($min_price) && !empty($max_price)){
$t5 = " AND `price` <= '".$max_price."'";
}
$sql = $mysqli->query("SELECT * FROM `project` WHERE `status`='1' ".
$t1." ".$t2." ".$t3." ".$t4." ".$t5." ".
"ORDER BY `posted_date` DESC LIMIT ".$start.", ".$per_page);
if($sql->num_rows > 0){
return $sql;
}else{
return false;
}
}
The query output will something like:
SELECT * FROM `project`
WHERE `proj_title` LIKE '%keywords%'
OR `proj_addr` LIKE '%keywords%'
OR `proj_area` LIKE '%keywords%'
AND `proj_for`='Sale' AND `state`='Somewhere' AND `proj_cat`='8' AND `price` BETWEEN '250000' AND '600000'
(Datatype for price is DECIMAL(10,2), it stored value like 250000.00)
However, the returned results is not like expected (not accurate), its also will come out a result with price more than 600000 and project category which is out of '8' which is not fancy for the end user to searching in the website.
is there any way to refine on the query to perform more specific?

Instead of taking these variables you should use ".=" operator.
/* $t1 = '';
$t2 = '';
$t3 = '';
$t4 = '';
$t5 = '';
*/
$q = "SELECT * FROM `property` WHERE `status`='1' ";
// You need to enclose all **OR** logical tests in parenthesis.
// Moreover most of the usages of isset function are useless,
// as your are initializing many variables
if($keyword && !empty($keyword)){
$q .= " AND (`p_title` LIKE '%".$keyword."%' OR `address` LIKE '%".$keyword."%' OR `area` LIKE '%".$keyword."%')";
}
if($prop_for && !empty($prop_for)){
// If you are using double quotes you really don't need handle to concatenation.
$q .= " AND `p_for`='$prop_for'";
}
if($state && !empty($state)){
$q .= " AND `state`='$state'";
}
if($ptype && !empty($ptype)){
$q .= " AND `p_category`='$ptype'";
}
//min only
if($min_price && !empty($min_price)){
$q .= " AND `price` >= '".$min_price."'";
}
//max only
if($max_price && !empty($max_price)){
$q .= " AND `price` <= '$max_price'";
}
// When you are not using OFFSET keyword,
//the first number after LIMIT keyword should be the number of records
$q .= " ORDER BY `posted_date` DESC LIMIT $per_page , $start;";
$sql = $mysqli->query($q);

You're going to need parentheses.
SELECT * FROM `project` WHERE (`proj_title` LIKE '%keywords%' OR `proj_addr` LIKE '%keywords%' OR `proj_area` LIKE '%keywords%') AND `proj_for`='Sale' AND `state`='Somewhere' AND `proj_cat`='8' AND `price` BETWEEN '250000' AND '600000'
Without the parentheses it just has to match one of the criteria before the last OR.

if(isset($_SESSION['login']))
{
echo "<div align=\"right\"><strong> Home |
Signout|
Profile</strong></div>";
}
else
{
echo " ";
}
$con= mysql_connect("localhost","root","");
$d=mysql_select_db("matrimonial",$con);
$gender=$_POST['gender'];
$age1=$_POST['age1'];
$age2=$_POST['age2'];
$city=$_POST['city'];
$subcast=$_POST['subcast'];
$result=mysql_query("select * from matri where gender='$gender' and age between '$age1' and '$age2' and city='$city' and subcast='$subcast'");
if($gender && !empty($gender))
{
$result .= " AND `gender`='$gender'";
}
if($age1 && !empty($age1)){
$result .= " AND `age`='$age1'";
}
if($age2 && !empty($age2)){
$result .= " AND `age`='$age2'";
}
if($city && !empty($city)){
$result .= " AND `city`='$city'";
}
if($subcast && !empty($subcast)){
$result .= " AND `subcast`='$subcast'";
}
$result .= " select * from ";
$sql = $mysql->query($result);
how to run this code

On the price difference you should do a if the price if between the 2 values else only 1 value.

Related

PHP MySQL Advance Search with Check boxes

I am trying to build search logic that uses multiple form fields and adjusts the MySQL search accordingly. My main area of issue is when dealing with multiple checkboxes. The below gets me close but I get multiple "OR" at the end for some reason. The below gives me (nema = '1' OR OR nema = '12' OR OR nema = '4' OR OR ) for example. More OR's are added for each checkbox. What am I missing or not doing correctly?
$rating = mysqli_real_escape_string($db, implode(',', $_POST['rating']));
$q = "SELECT * FROM lekker WHERE height BETWEEN 20 AND 30 ";
if (!empty($rating)) {
$var = explode(',',$rating);
$rating_count = count($var);
if($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test'";
for($i=0;$i<$rating_count;$i++) {
if($i!=$rating_count-1) {
$q .= " OR ";
}
}
}
$q .= " )";
} else {
$q .= "nema = '$rating'";
}
}
$q .= " ORDER BY `part` ASC";
This is the Select I am trying to achieve:
SELECT * FROM lekker WHERE height BETWEEN 20 AND 22 AND (nema = '1' OR nema = '12') ORDER BY part ASC
I removed the second loop and always add OR, then you can remove the last one at the end
$rating = mysqli_real_escape_string($db, implode(',', $_POST['rating']));
$q = "SELECT * FROM lekker WHERE height BETWEEN 20 AND 30 ";
if (!empty($rating)) {
$var = explode(',',$rating);
$rating_count = count($var);
if($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test' OR ";
}
$q=substr($q, 0,-4);
$q .= " )";
} else {
$q .= "nema = '$rating'";
}
}
$q .= " ORDER BY `part` ASC";
Instead of worrying about whether or not you need to add an OR simply add it each time through your foreach then trim off the trailing OR after you are done with the foreach.
if ($rating_count > 1) {
$q .= "AND (";
foreach($var as $test) {
$q .= "nema = '$test' OR ";
}
$q .= rtrim($q,' OR ') . ' )';
} else {
$q .= "nema = '$rating'";
}

Querying mySQL database with dropdown values

I've got below snippet where $filter_xx values are extracted from a dropdown basis user choice.
I'm trying to query the mySQL database with what the user chose to query the database with via dropdown selection.
You will see that there are 4 $filter_xx variables and how many of them are set in a given instance is completely random.
The issue is when I use && in the query it checks if all four parameters are true and then throws and output. (Well I know && is suppose to work that way!). I tried replacing all && operators with || and had no luck.
How do I search the database with only options selected by the user?
if(isset($filter_brand) || isset($filter_year) || isset($filter_month) || isset($filter_status))
{
$query = "SELECT * FROM targets WHERE brand='$filter_brand' && startyear='$filter_year' && startmonth='$filter_month' && status='$filter_status' ORDER BY createdon DESC";
} else {
$query = "SELECT * FROM targets ORDER BY createdon DESC";
}
When you have several values that must work in a similar manner, use an array together with loop. I am supposing, you are using mysqli, change quoting for PDO if needed.
$mysqli = new mysqli("localhost", "user", "pass", "test");
//...
//SQL attr name => name of POST parameter
$filter = array('brand' => 'brand', 'startyear' => 'year',
'startmonth' => 'month', 'status' => 'status');
//here we'll store SQL conditions
$sql_filter = array();
foreach($filter as $key => $value)
{
if (isset($_POST[$value]))
{
//use your library function to quote the variable before using it in SQL
$sql_filter[] = $key . '="'. $mysqli->escape_string($_POST[$value]) . '"';
}
}
$query = "SELECT * FROM targets ";
if(isset($sql_filter[0]))
{
$query .= 'WHERE ' . implode(' AND ', $sql_filter) . ' ';
}
$query .= 'ORDER BY createdon DESC';
Try By This
$join = "";
//TAKE ONE BLANK VARIBLE THAT JOIN IF VALUE IS SET
if(isset($filter_brand)){
//IF VALUE ISSET THAN IT ADDED TO QUERY
$join .= " AND brand='$filter_brand'";
}
if(isset($filter_year){
$join .= " AND startyear='$filter_year'";
}
$query = "SELECT * FROM targets WHERE id != '' $join ORDER BY createdon DESC";
You can do something like this:
$query = 'SELECT * FROM targets';
$flag = 0;
if(isset($filter_brand) )
{
$query = "SELECT * FROM targets WHERE brand='$filter_brand'";
$flag = 1;
}
if(isset($filter_year)) {
if($flag==1)
$query .= " &&";
$query .= " startyear='$filter_year'";
$flag = 1;
}
if(isset($filter_month)) {
if($flag==1)
$query .= " &&";
$query = " startmonth='$filter_month'";
$flag = 1;
}
if(isset($filter_status)){
if($flag==1)
$query .= " &&";
$query = " status='$filter_status'";
$flag = 1;
}
if($flag == 1){
$query .= " ORDER BY createdon DESC";
} else {
$query = "SELECT * FROM targets ORDER BY createdon DESC";
}
Try this:
$query = "SELECT * FROM targets WHERE 1 ";
$query = isset($filter_brand) ? $query . " AND brand = '".$filter_brand."'" : $query;
$query = isset($filter_year) ? $query . " AND startyear = '".$filter_year."'" : $query;
$query = isset($filter_month) ? $query . " AND startmonth = '".$filter_month."'" : $query;
$query = isset($filter_status) ? $query . " AND status = '".$filter_status."'" : $query;
$query .= " ORDER BY createdon DESC";

PHP search to match all if the term is empty

I have written a simple search algorithm for my advanced search of my website.
There are several categories that the advanced search helps the user to limit his/her search. %$variable% is the matching that I use. I want the database to return every possible matches if the title is empty...what should be added/removed to/from this code?
if(isset($_POST['type']) && $_POST['type'] != 0)
{
$type = $_POST['type'];
if($wh == true)
{
$statement .= " AND `type` = '$type' ";
}
else
{
$wh = false;
$statement .= " WHERE `type` = '$type' ";
}
}
if(isset($_POST['sex']) && $_POST['sex'] != 0)
{
$sex = $_POST['sex'];
if($wh == true)
{
$statement .= " AND `sex` = '$sex' ";
}
else
{
$wh = false;
$statement .= " WHERE `sex` = '$sex' ";
}
}
if(isset($_POST['start']) && $_POST['start'] != 0)
{
$start = $_POST['start'];
if($wh == true)
{
$statement .= " AND `start` > '$start' ";
}
else
{
$wh = false;
$statement .= " WHERE `start` > '$start' ";
}
}
if($wh==true)
{
$statement .= " $branch_sentence AND( `title` LIKE '%$search_term%' OR `content` LIKE '%$search_term%' OR `keywords` LIKE '%$search_term%') ORDER BY stars DESC ";
}
else
{
$statement .= " WHERE `title` LIKE '%$search_term%' OR `content` LIKE '%$search_term%' OR `keywords` LIKE '%$search_term%' ORDER BY stars DESC ";
}
// echo $statement;
if($transorder = $site_db->query($statement))
{
$i=0;
while($row_obj = $transorder->fetch_object())
{
$item[$i]['id'] = $row_obj->id;
$item[$i]['pic_main'] = $row_obj->pic_main;
$item[$i]['title'] = $row_obj->title;
$item[$i]['province'] = $row_obj->province;
$item[$i]['stars'] = $row_obj->stars;
$i++;
}
}
}
}
What's wrong with:
if (empty($_POST['title']))
{
$statement = "SELECT id, pic_main, title, province, stars FROM "; // Incomplete b/c I don't know your table name from the question.
}
?

search query in php

I am creating search query in php by passing variable through GET method. When the variable is null then it's passing the query like,
SELECT * FROM table WHERE column_name = null.
And it's showing error (obvious). I want to create query like. If user don't select anything from search options then it should fetch all the data from that column.
What's the correct logic for that?
Thanks.
Code:
if(isset($_GET['selPetType']) && $_GET['selPetType'] != '')
{
$searchParams['petType'] = $_GET['selPetType'];
$queryStr .= " PetType='" .$_GET['selPetType']. "'";
}
if(isset($_GET['txtPetBreed1']) && !empty($_GET['txtPetBreed1']))
{
$searchParams['breed'] = $_GET['txtPetBreed1'];
$queryStr .= " AND PetBreed1 ='". $_GET['txtPetBreed1'] . "'";
}
$clause1 = "SELECT * FROM pet WHERE $queryStr ORDER BY `Avatar` ASC LIMIT $startLimit, $pageLimit";
$totalRun1 = $allQuery->run($clause1);
Maybe something like this:
$get['param1'] = 'foo';
$get['param3'] = null;
$get['param2'] = '';
$get['param4'] = 'bar';
$where = null;
foreach ($get as $col => $val) {
if (!empty($val)) {
$where[] = $col . ' = "' . $val . '"';
}
}
$select = 'SELECT * FROM pet ';
if ($where) {
$select .= 'WHERE ' . implode(' AND ', $where);
}
$select .= ' ORDER BY `Avatar` ASC LIMIT $startLimit, $pageLimit';
Edit: I added if to remove empty values and added 2 new values to example so you can see this values will not be in query.
if(isset($_GET['your_variable'])){
$whr = "column_name = $_GET['your_variable']";
}
else{
$whr = "1 = 1";
}
$qry ="SELECT * FROM table WHERE ".$whr;
For example :
<?php
$userSelectedValue = ...;
$whereCondition = $userSelectedValue ? " AND column_name = " . $userSelectedValue : "" ;
$query = "SELECT * FROM table WHERE 1" . $whereCondition;
?>
Then consider it's more safe to use prepared statements.

PHP and MySQL optional WHERE conditions

I have the following problem: I want to let a user apply filters to a DB search.
I have three filters, A, B and C. All of them can be "empty", as in, the user doesn't care about them and selects "Any". Now I want to check this query against the DB records. I use a normal mysql query as in
$db_q = "Select * from table where row1 = '" . $A . "' and row2 = '" . $B . "' and row3 =
'" . $C . "'";
This works fine as long as the user enters anything specific for A,B,C (!= "any"). When "any" is selected, i get something like this: "Select * from table where row1 = "any/all" etc." I can't seem to figure out the correct syntax (if it's even possible) and I would like to avoid messy case distinction (if A == any, perform select; if B == empty.. and so on).
Any help is much appreciated.
The other answers are mostly correct, but this is a simpler way to accomplish what is needed:
$where = array();
if($A != 'any'){ // or whatever you need
$where[] = "A = $A'";
}
if($B != 'any'){ // or whatever you need
$where[] = "B = $B'";
}
if($C != 'any'){ // or whatever you need
$where[] = "C = $C'";
}
$where_string = implode(' AND ' , $where);
$query = "SELECT * FROM table";
if($where){
$query .= ' ' . $where_string;
}
This will allow for any combination of conditions and expansion.
Before your query you could use:
$tmp = "where ";
if($A and $A!="any" and $A!="not used")
$tmp .= "row1 = '".$A."'";
if($B and $B!="any" and $B!="not used")
$tmp .= "AND row2 = '".$B. "'";
if($C and $C!="any" and $C!="not used")
$tmp .= "AND row3 = '".$C."'";
$db_q = "Select * from table $tmp";
Try this:
$db_q = "Select * from table ";
if ($A != "any" || $B != "any" || $C != "any")
{
$db_q .= "where ";
}
$firstCondition = true;
if ($A != "any")
{
if (!$firstCondition)
$db_q .= "and ";
$db_q .= "row1 = '$A' ";
$firstCondition = false;
}
if ($B != "any")
{
if (!$firstCondition)
$db_q .= "and ";
$db_q .= "row2 = '$B' ";
$firstCondition = false;
}
if ($C != "any")
{
if (!$firstCondition)
$db_q .= "and ";
$db_q .= "row3 = '$C' ";
$firstCondition = false;
}
Try doing something like this:
if #param1 is not null
select * from table1 where col1 = #param1
else
select * from table1 where col2 = #param2
This can be rewritten:
select * from table1
where (#param1 is null or col1 = #param1)
and (#param2 is null or col2 = #param2)
Got the idea from Baron Schwartz's blog: https://www.xaprb.com/blog/2005/12/11/optional-parameters-in-the-where-clause/

Categories