MYSQL multiple words search result - php

When I type about three keywords or more it seems to only search the first keyword i.e bolt nut washer it will only search bolt.
I would like to search multiple keywords or the complete search term when inputted.
This is the code:
if (!(isset($_GET['pagenum']))) {
$pagenum = 1;
} else {
$pagenum = $_GET['pagenum'];
}
$page_limit = ($_GET["show"] <> "" && is_numeric($_GET["show"]) ) ? $_GET["show"] : 8;
try {
$keyword = trim($_GET["keyword"]);
if ($keyword <> "" ) {
$sql = "SELECT * FROM tbl_contacts WHERE 1 AND "
. " (first_name LIKE :keyword OR contact_no1 LIKE :keyword) ORDER BY first_name ";
$stmt = $DB->prepare($sql);
$stmt->bindValue(":keyword", $keyword."%");
} else {
$sql = "SELECT * FROM tbl_contacts WHERE 1 ORDER BY first_name ";
$stmt = $DB->prepare($sql);
}
$stmt->execute();
$total_count = count($stmt->fetchAll());
$last = ceil($total_count / $page_limit);
if ($pagenum < 1) {
num < 1) {
} elseif ($pagenum > $last) {
$pagenum = $last;
}
$lower_limit = ($pagenum - 1) * $page_limit;
$lower_limit = ($lower_limit < 0) ? 0 : $lower_limit;
$sql2 = $sql . " limit " . ($lower_limit) . " , " . ($page_limit) . " ";
$stmt = $DB->prepare($sql2);
if ($keyword <> "" ) {
$stmt->bindValue(":keyword", $keyword."%");
$stmt->execute();
$results = $stmt->fetchAll();
}
} catch (Exception $ex) {
echo $ex->getMessage();
}

I figured it out. Fixed by changing:
. " (first_name LIKE :keyword OR contact_no1 LIKE :keyword) ORDER BY first_name ";
to
. " (first_name LIKE '%".$keyword."%' OR contact_no1 LIKE '%".$keyword."%') ORDER BY last_name DESC ";
Now the search returns any keyword entered

Related

Converting to PDO Parameter Binding

I'm using SensioLabsInsight to profile any vulnerabilities in my code.
I've received several errors for possible sql injection, and it recommends using parameter binding with PDO. This is fine since I'm already using PDO for my db driver.
Right now my model is passed a $data array and then checks for specific values in the array in order to add to the sql query if present, like so:
public function getDownloads($data = array()) {
$sql = "
SELECT *
FROM {$this->db->prefix}download d
LEFT JOIN {$this->db->prefix}download_description dd
ON (d.download_id = dd.download_id)
WHERE dd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
if (!empty($data['filter_name'])) {
$sql .= " AND dd.name LIKE '" . $this->db->escape($data['filter_name']) . "%'";
}
$sort_data = array(
'dd.name',
'd.remaining'
);
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
$sql .= " ORDER BY " . $data['sort'];
} else {
$sql .= " ORDER BY dd.name";
}
if (isset($data['order']) && ($data['order'] == 'DESC')) {
$sql .= " DESC";
} else {
$sql .= " ASC";
}
if (isset($data['start']) || isset($data['limit'])) {
if ($data['start'] < 0) {
$data['start'] = 0;
}
if ($data['limit'] < 1) {
$data['limit'] = 20;
}
$sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
}
$query = $this->db->query($sql);
return $query->rows;
}
The error referenced from the SensioLabsInsight analysis references only the $data['sort'] clause as being a possible injection point.
My question is, do I need to test for $data array presence when creating a prepare statement, or will it simply return null if the array value is empty.
My proposed new query with parameter binding would look like so:
public function getDownloads($data = array()) {
$sql = "
SELECT *
FROM {$this->db->prefix}download d
LEFT JOIN {$this->db->prefix}download_description dd
ON (d.download_id = dd.download_id)
WHERE dd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
if (!empty($data['filter_name'])) {
$sql .= " AND dd.name LIKE :filter_name%";
}
$sort_data = array(
'dd.name',
'd.remaining'
);
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
$sql .= " ORDER BY :sort";
} else {
$sql .= " ORDER BY dd.name";
}
if (isset($data['order']) && ($data['order'] == 'DESC')) {
$sql .= " DESC";
} else {
$sql .= " ASC";
}
if (isset($data['start']) || isset($data['limit'])) {
if ($data['start'] < 0) {
$data['start'] = 0;
}
if ($data['limit'] < 1) {
$data['limit'] = 20;
}
$sql .= " LIMIT :start, :limit";
}
$this->db->prepare($sql);
$this->db->bindParam(':filter_name', $data['filter_name']);
$this->db->bindParam(':sort', $data['sort']);
$this->db->bindParam(':start', $data['start'], PDO::PARAM_INT);
$this->db->bindParam(':limit', $data['limit'], PDO::PARAM_INT);
$query = $this->db->execute();
return $query->rows;
}
Will this work as is, or do the parameter bindings need to be moved within the if/else conditionals?

PHP MySQL search with multiple criteria

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.

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.
}
?

Improving my SELECTs that use PDO and adding an UPDATE statement

I'm using the following code to select data from a MySQL table. Can someone tell me how to improve this as it seems a bit messy?
Also, I need to run an UPDATE statement to increment the value in the "views" column each time a customer is queried from the database. Each customer row in the database has a column named "views". For example, say ABC Corp has 100 views. If I search for ABC Corp and the database returns the record, the "views" column for this record should be updated to 101. What is the best way to do this?
if ($search && ($group && $group !== "*")) {
$sql = "SELECT * FROM customers WHERE description LIKE :description AND groupId LIKE :groupId";
$result = $conn->prepare($sql);
$result->bindValue(":description", "%" . $search . "%", PDO::PARAM_STR);
$result->bindValue(":groupId", $groupId, PDO::PARAM_INT);
} else if ($search) {
$sql = "SELECT * FROM customers WHERE description LIKE :description";
$result = $conn->prepare($sql);
$result->bindValue(":description", "%" . $search . "%", PDO::PARAM_STR);
} else if ($group !== "*") {
$sql = "SELECT * FROM customers WHERE groupId LIKE :groupId";
$result = $conn->prepare($sql);
$result->bindValue(":groupId", $groupId, PDO::PARAM_INT);
} else {
$sql = "SELECT * FROM customers";
$result = $conn->prepare($sql);
}
How about something like this,
$sql = "SELECT * FROM customers ";
$and = $grp = FALSE;
if($search || ($group && $group !== "*") {
$sql .= " WHERE ";
if ($search) {
$sql .= " description LIKE :description ";
$and = TRUE;
}
if ($group && $group !== "*") {
if( $and === TRUE )
$sql .= " AND ";
$sql .= " groupId LIKE :groupId ";
$grp = TRUE;
}
}
$result = $conn->prepare($sql);
if( $and === TRUE)
$result->bindValue(":description", "%" . $search . "%", PDO::PARAM_STR);
if( $grp === TRUE)
$result->bindValue(":groupId", $groupId, PDO::PARAM_INT);
For the UPDATE statement,
//say $cust_name is the requested customer to be searched
$sql = "SELECT views from customers where customer_name = '" $cust_name."'";
$res = $conn->query($sql);
$views = $res->fetchColumn() + 1;
//sets 'views' to num_of_customers/rows returned.
$sql = "UPDATE customers SET VIEWS = " .$views." WHERE customer_name = '" $cust_name."'";
$res = $conn->query($sql);

While Loop in SQL query

I'm not sure why this SQL query is not working.
I'm new to SQL/PHP so please forgive.
mysql_query("
SELECT * FROM table WHERE name = " . "'Bob'" .
while($i < $size)
{
$i++;
echo "OR name = '";
echo $array[$i] . "'";
} .
" ORDER BY id DESC "
);
Dreamweaver gives me an error saying it is not correct but does not tell me what is wrong.
Is it possible to put a while loop into an sql command?
you can not use a while in a string
$where = "";
if ($size > 0)
{
$where .= " WHERE ";
}
while($i < $size)
{
$i++;
$where .= "OR name = '".$array[$i]."' ";
}
$query = "SELECT * FROM table WHERE name = '".Bob."'".$where." ORDER BY id DESC";
mysql_query($query);
(this code is not tested)
Woot !
You just can't write this :D
Build your OR condition before writing the query and it will be just fine:
$myCondition = " ";
while($i < $size) {
$i++;
$myCondition .= "OR name = '" . $array[$i] . "'";
}
mysql_query(
"SELECT * FROM table WHERE name = " . "'Bob'" . $myCondition . " ORDER BY id DESC ");
echo is to output the string, and it won't return the string.
Something like $str = "aaa" . echo "bbb"; won't work.
For you case, use IN will be better.
foreach ($array as &$name) {
$name = "'".mysql_real_escape_string($name)."'";
}
mysql_query("SELECT * FROM table WHERE name IN (".implode(',', $array).")");
Or use
"SELECT * FROM table WHERE name IN(".implode( ',', $array).")";

Categories