Creating conditional sql query - php

I am having a problem getting a query to work (and also am questioning the security of the query).
if(isset($_POST)){
$sql = "SELECT * FROM members WHERE";
if($_POST['FirstName_S'] !== ''){
$sql .= " FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
}
if($_POST['LastName_S'] !== ''){
$sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
}
if($_POST['Firm_S'] !== ''){
$sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
}
if($_POST['Country_S'] !== ''){
$sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
}
if($_POST['City_S'] !== ''){
$sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
}
if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
$sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
}
}
Obviously, if FirstName_S is undefined, the query breaks saying "WHERE OR". It seems like it would have a logical fix, but I've been staring at it for a little too long.
Also, sql injection was brought up as a concern, and as a side-question, would sanitizing the input be enough? Or is this altogether bad practice?

if(isset($_POST)){
$sql = "SELECT * FROM members WHERE";
if($_POST['FirstName_S'] !== ''){
$sql .= "OR FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
}
if($_POST['LastName_S'] !== ''){
$sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
}
if($_POST['Firm_S'] !== ''){
$sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
}
if($_POST['Country_S'] !== ''){
$sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
}
if($_POST['City_S'] !== ''){
$sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
}
if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
$sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
}
$sql=str_replace("WHERE OR","WHERE",$sql); // quick dirty fix
}
Ofcourse you'd need to sanitize the input, but since you didn't mention which MySQL API you use, I did not add any sanitization functions yet. You can look at http://php.net/mysqli_real_escape_string

do it other way as follow
if(isset($_POST)){
$sql = "SELECT * FROM members WHERE";
if($_POST['FirstName_S'] !== ''){
$sql_arr[]=" FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
}
if($_POST['LastName_S'] !== ''){
$sql_arr[]= " LastName LIKE '%" . $_POST['LastName_S'] . "%'";
}
if($_POST['Firm_S'] !== ''){
$sql_arr[]= " Firm LIKE '%" . $_POST['Firm_S'] . "%'";
}
if($_POST['Country_S'] !== ''){
$sql_arr[]= " Country LIKE '%" . $_POST['Country_S'] . "%'";
}
if($_POST['City_S'] !== ''){
$sql_arr[]= " City LIKE '%" . $_POST['City_S'] . "%'";
}
if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
$sql_arr[]= " State LIKE '%" . $_POST['State_S'] . "%'";
}
if(!empty($sql_arr)){
$sql.=implode(' OR ',$sql_arr);
}
}

The quick fix is to add 1=1 to your query, so your query ends with WHERE 1=1. That allows you to be free to append any number of OR something to your query, without being concerned with omitting the OR on the first one.
(That 1=1 predicate doesn't cause any problem; that will be evaluated at parse time, and doesn't appear in the execution plan.)
As to SQL Injection, yes, this code is susceptible. If you are using mysql interface, then sanitize the post variables with mysql_real_escape_string function. If you are using mysqli or PDO (and you should be), then use parameterized queries.

$stmt = $dbConnection->prepare('SELECT * FROM members WHERE FirstName LIKE ? OR LastName LIKE ? OR FIRM LIKE ? OR Country LIKE ? OR CITY LIKE ? OR STATE LIKE ?');
if($_POST['FirstName_S'] !== ''){
$stmt->bind_param('FirstName', '%'.$_POST['FirstName_S'].'%');
} else {
$stmt->bind_param('FirstName', '%');
}
… // do this for all your parameters
$stmt->execute();

I think this could help you:
if(isset($_POST)){
$sql = "SELECT * FROM members";
if($_POST['FirstName_S'] !== ''){
$sql .= " WHERE FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
}
else {
$sql .= " WHERE FirstName LIKE '%'";
}
if($_POST['LastName_S'] !== ''){
$sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
}
if($_POST['Firm_S'] !== ''){
$sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
}
if($_POST['Country_S'] !== ''){
$sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
}
if($_POST['City_S'] !== ''){
$sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
}
if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
$sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
}
}
and for the SQL injections, you can check General_Twyckenham comment.

You could compose the WHERE command based on what parameters is entered...
if(isset($_POST)){
$sql_where = '';
$sql = "SELECT * FROM members ";
if($_POST['FirstName_S'] !== ''){
$sql_where .= (($sql_where != '')?('OR '):(''))." FirstName LIKE '%" . $_POST['FirstName_S'] . "%' ";
}
if($_POST['LastName_S'] !== ''){
$sql_where .= (($sql_where != '')?('OR '):(''))." LastName LIKE '%" . $_POST['LastName_S'] . "%' ";
}
if($_POST['Firm_S'] !== ''){
$sql_where .= (($sql_where != '')?('OR '):(''))." Firm LIKE '%" . $_POST['Firm_S'] . "%' ";
}
if($_POST['Country_S'] !== ''){
$sql_where .= (($sql_where != '')?('OR '):(''))." Country LIKE '%" . $_POST['Country_S'] . "%' ";
}
if($_POST['City_S'] !== ''){
$sql_where .= (($sql_where != '')?('OR '):(''))." City LIKE '%" . $_POST['City_S'] . "%' ";
}
if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
$sql_where .= (($sql_where != '')?('OR '):(''))." State LIKE '%" . $_POST['State_S'] . "%' ";
}
$sql .= (($sql_where != '')?('WHERE '.sql_where):(''));
}

Related

PHP SQL: Order search query results by user input order

I've tried to look for a solution but can't seem to grasp the issue I have.
I have a search query with a "where clause" stating if a user inputs multiple words return the result.
I need the result returned in the same order searched.
Even if i just add the addition "ORDER BY DESC" an error is thrown "Trying to get property of non-object".
Here is my code:
$word = $_GET['word'];
$word3 = $_GET['word'];
$word = explode(";", $word);
$noOfWords = count($word);
$word2 = $word3;
if ($noOfWords == 1) {
$searchString = " word_eng LIKE '" . $conn->escape_string($word3)
"%'";
} else {
$searchString = $whereClause = "";
foreach ($word as $entry) {
$searchString .= " OR word_eng LIKE '" . $conn->escape_string($entry) . "' ORDER BY '" . $word2 . "' ";
}
}
$whereClause = ($searchString != "") ? " WHERE " . preg_replace('/OR/',
'', $searchString, 1) : $whereClause;
$sql = "SELECT word_eng FROM words " . $whereClause . " LIMIT 17";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$row1 = $row["word_eng"];
echo $row1;
}
There are a couple of problems with the way your trying to use ORDER BY. There should be only 1 order by clause in any SQL, you are adding it in for each word your adding. The second part is that it's expecting to order by a column name and your ordering it by the words your searching for.
With wanting to maintain the order of the terms and the order of the results, it would be necessary to use an order by clause with something like a case (Can you add an if statement in ORDER BY? may help explain this).
$orderBy = "";
if ($noOfWords == 1) {
$searchString = " word_eng LIKE '" . $conn->escape_string($word3) ."%'";
} else {
$searchString = $whereClause = "";
$orderBy = " order by case `word_eng` ";
foreach ($word as $order=>$entry) {
$searchString .= " OR word_eng LIKE '" . $conn->escape_string($entry) . "'";
$orderBy .= " when '$entry' then $order ";
}
$orderBy .= " end ";
}
$whereClause = ($searchString != "") ? " WHERE " . preg_replace('/OR/',
'', $searchString, 1) : $whereClause;
$sql = "SELECT word_eng FROM words " . $whereClause . " " .$orderBy." LIMIT 17";
if ($noOfWords == 1) {
$searchString = " word_eng LIKE '" . $conn->escape_string($word3)
"%'";
} else {
$searchString = $whereClause = "";
foreach ($word as $entry) {
$searchString .= " OR word_eng LIKE '" . $conn->escape_string($entry);
}
$searchString .= "' ORDER BY '" . $word2 . "' ";
}
I think you messed up with MySQL Query string in bellow line code.
$searchString .= " OR word_eng LIKE '" . $conn->escape_string($entry) . "' ORDER BY '" . $word2 . "' ";
Your Query is generating Something like
ORDER BY DESC
And OrderBy Query should be something like this
ORDER BY expression [ ASC | DESC ];
So you are missing the expression in query.

Check for spelling mistakes in where clause SQL PHP

I have an sql search query that returns the matched values within a where clause. I need to update this - so for example, if someone searches "elephhant" it will return the result "elephant". How do I go about doing this? Thanks
$the_word = GET['word_eng'];
$split = substr($the_word, 0, 3);
if ($noOfWords == 1) {
$searchString = " word_eng LIKE '" . $the_word ."%'";
}
else {
$searchString = $whereClause = "";
$orderBy = " order by case `word_eng` ";
foreach ($word as $order=>$entry) {
$searchString .= " OR word_eng LIKE '" . $entry . "'";
$orderBy .= " when '$entry' then $order ";
}
$orderBy .= " end ";
}
$whereClause = ($searchString != "") ? " WHERE " . preg_replace('/OR/',
'', $searchString, 1) : $whereClause;
$sql = "SELECT word_eng FROM words " . $whereClause . " OR word_eng LIKE '" .$split "%' " .$orderBy." LIMIT 50";
$result = $conn->query($sql);

Number conversion using urlencode

I'm having some trouble passing a number to a GET sting in php, using a urlencode and then urldecode (have tried both the standard urlencode and rawurlencode). The problem is limited to numerical values, as my code works fine for everything else.
Here are relevant sections of code:
if (isset($_GET['q'])) {
$qry = $_GET['q'];
$qry = urldecode($qry);
}
This is the code used for searching:
$qry = "SELECT * FROM jobs JOIN clients ON jobs.Client = clients.ClientCode WHERE JobNumber LIKE '%1%'";
if (isset($_GET['DP']) && (strlen($_GET['DP']) > 0)) {
$qry .= " AND DP LIKE %" . $_GET['DP'] . "%";
} elseif (isset($_POST['DP']) && (strlen($_POST['DP']) > 0)) {
$qry .= " AND DP LIKE '%" . $_POST['DP'] . "%'";
}
if (isset($_GET['JobDescription'])) {
$qry .= " AND JobDescription LIKE '%" . $_GET['JobDescription'] . "%'";
} elseif (isset($_POST['JobDescription']) && (strlen($_POST['JobDescription']) > 0)) {
$qry .= " AND JobDescription LIKE '%" . $_POST['JobDescription'] . "%'";
}
if (isset($_GET['JobNumber'])) {
$qry .= " AND JobNumber LIKE '%" . $_GET['JobNumber'] . "%'";
} elseif (isset($_POST['JobNumber']) && (strlen($_POST['JobNumber']) > 0)) {
$qry .= " AND JobNumber LIKE '%" . $_POST['JobNumber'] . "%'";
}
This is the code used to encode the query after it has been processed:
$qry = urlencode($qry);
A string is output to be used in the pagination, an example being
http://localhost/cpc/jobsearch.php?page=2&q=SELECT+%2A+FROM+jobs+JOIN+clients+ON+jobs.Client+%3D+clients.ClientCode+WHERE+JobNumber+LIKE+%27%251%25%27+AND+DP+LIKE+%27%25754611%25%27
This is causing errors around the 754611 section of the url, and the page does not preform as intended. I believe it has something to do with the %25 (which represents a % sign, and is needed for the search) running into the value (754611 in this case) and not being decoded properly.
What am I doing wrong?

PHP PDO how to bind values to varibale contains concatenated string

How do i bind values to a variable which is partially processed with diffrent statements and then concatenated using php .= method
Please note that I am not using array to bind parameters.
below is piece of code
$wher = '';
now I have added few varibles to $wher like
if (!empty($_SESSION['advs']['title']))
{
$wher .= '(';
if (isset($_SESSION['advs']['desc']))
{
$wher .= "(au.description like '%" . $system->cleanvars($_SESSION['advs']['title']) . "%') OR ";
}
$wher .= "(au.title like '%" . $system->cleanvars($_SESSION['advs']['title']) . "%' OR au.id = " . intval($_SESSION['advs']['title']) . ")) AND ";
}
more addition to $wher
if (isset($_SESSION['advs']['buyitnow']))
{
$wher .= "(au.buy_now > 0 AND (au.bn_only = 'y' OR au.bn_only = 'n' && (au.num_bids = 0 OR (au.reserve_price > 0 AND au.current_bid < au.reserve_price)))) AND ";
}
if (isset($_SESSION['advs']['buyitnowonly']))
{
$wher .= "(au.bn_only = 'y') AND ";
}
if (!empty($_SESSION['advs']['zipcode']))
{
$userjoin = "LEFT JOIN " . $DBPrefix . "users u ON (u.id = au.user)";
$wher .= "(u.zip LIKE '%" . $system->cleanvars($_SESSION['advs']['zipcode']) . "%') AND ";
}
now I am using $wher in database query like
// get total number of records
$query = "SELECT count(*) AS total FROM " . $DBPrefix . "auctions au
" . $userjoin . "
WHERE au.suspended = 0
AND ".$wher . $ora . "
au.starts <= " . $NOW . "
ORDER BY " . $by;
$wher is being used in SQL select query.
How do I put placeholders to $wher and bind the values??
my problem is something like PHP PDO binding variables to a string while concatenating it
But slight different way

SQL Query from multiple text inputs

I am trying to collect info from four separate text fields and generate queries in the backend to display the results. I have tried many solutions already suggested on here but I keep getting duplicate results.
I have it working with one query:
<?php
$query = "SELECT * FROM book WHERE booktitle LIKE '%" . mysql_real_escape_string($_POST['title']) . "%'";
$result = mysqli_query($con, $query) or die("Error in query");
while ($row = mysqli_fetch_array($result)) {
?>
<img src="<?php echo $row[12]; ?>" width="112px" height="150px" />
<?php
echo "<b>Title: </b>" . $row[1] . "<br />";
echo "<b>Author: </b>" . $row[2] . "<br />";
echo "<b>Price:</b> £" . $row[9] . "<br />";
echo "<b>Description:</b> " . substr($row[3],0,320) . "...<br /><hr>";
}
But I also need to incorporate results from the other 3 somehow??
$query = "SELECT * FROM book WHERE author LIKE '%" . mysql_real_escape_string($_POST['author']) . "%'";
$query = "SELECT * FROM book WHERE isbn LIKE '%" . mysql_real_escape_string($_POST['isbn']) . "%'";
$query = "SELECT * FROM book WHERE description LIKE '%" . mysql_real_escape_string($_POST['keyword']) . "%'";
Any help would be greatly appreciated. Thanks in advance.
You can use an OR statement with the LIKE keyword to search all of these at the same time.
$query = "SELECT * FROM book WHERE booktitle LIKE '%" . $title . "%' OR author LIKE'%" . $author . "%' OR isbn LIKE '%" . $isbn . "%' OR description LIKE '%" . $keyword . "%';
If the variables are empty then you will have WHERE booktitle LIKE '%%', which returns all rows. You will need to build the query based on the input.
// Determine the WHEREs to use
$where = array();
if ( ! empty($title))
$where[] = "booktitle LIKE '%" . $title . "%'";
if ( ! empty($author))
$where[] = "author LIKE '%" . $author . "%'";
if ( ! empty($isbn))
$where[] = "isbn LIKE '%" . $isbn . "%'";
if ( ! empty($description))
$where[] = "description LIKE '%" . $description . "%'";
// Build the query
$query = 'SELECT * FROM book';
if ( ! empty($where))
$query .= ' WHERE ' . implode(' OR ', $where);
Note: I have omitted escaping the input for readability.
<?php
$mysqli = new mysqli("localhost", "username", "password", "database_name");
$book_title = mysql_real_escape_string($_POST['title']);
$author = mysql_real_escape_string($_POST['author']);
$isbn = mysql_real_escape_string($_POST['isbn']);
$keyword = mysql_real_escape_string($_POST['keyword']);
$query = "SELECT * FROM book WHERE booktitle LIKE '%{$book_title}' OR author LIKE'%" . $author . "%'
OR isbn LIKE '%" . $isbn . "%' OR description LIKE '%" . $keyword . "%'";
$result = $mysqli->query($query);
while($row = $result->fetch_array()):?>
<img src="<?=$row['image_column_name']; ?>" width="112px" height="150px" />
<b>Title:</b> <?=$row['title_column_name']; ?> <br>
<b>Author:</b> <?=$row['author_column_name']; ?> <br>
<b>Price:</b> <?=$row['price_column_name']; ?> <br>
<b>Description:</b> <?=substr($row['desc_column_name'],0,320)?>
<hr>
<?php endwhile; ?>

Categories