SQL string concatenation with if statement - php

I have simple query for full text search, data comes from HTML form inputs. If statement checks or it was filled all three inputs with array_key_exists and then concatenate all strings, but if someone didn't fill first or second input and then my query WHERE part is WHERE AND contract = $var so in this situation AND is not needed. What is solution for my problem, how i can solve this? When AND is needed just add to query string and when didn't needed don't add.
$sql = "SELECT
slug,
title,
company,
location,
email,
street,
city,
phone,
url,
description,
image,
created_at
FROM jobs
WHERE ";
array_key_exists('paieska', $segment) ? $sql .= "MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "AND contract = '".$segment['darbo-laikas']."' " : '';
array_key_exists('miestas', $segment) ? $sql .= "AND location = '".$segment['miestas']."'" : '';

The easiest solution is to just add a 1 to the original where statement (And AND before your first $sql if statement). This will always be true, and will return all the records.
If darbo-laikas exists, your query would be ...FROM jobs WHERE 1 AND contract... which would work correctly.
$sql = "SELECT
slug,
title,
company,
location,
email,
street,
city,
phone,
url,
description,
image,
created_at
FROM jobs
WHERE 1 ";
array_key_exists('paieska', $segment) ? $sql .= "AND MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "AND contract = '".$segment['darbo-laikas']."' " : '';
array_key_exists('miestas', $segment) ? $sql .= "AND location = '".$segment['miestas']."'" : '';

try this, add 'AND' in every last statement
array_key_exists('paieska', $segment) ? $sql .= "MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') AND " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "contract = '".$segment['darbo-laikas']."' AND " : '';
array_key_exists('miestas', $segment) ? $sql .= "location = '".$segment['miestas']."' AND " : '';
before execute, delete last char('AND') using
rtrim($sql, "AND ")
note: rtrim should with whitespace, because your 'AND ' using whitespace too

Related

How to use like in an in sql statement

Hi I'm using PHP to try and retrieve data from a database while looping through an array inside the in statement like this.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE FavorIDs IN (" ;
$count = 0;
foreach($followingArray as $value)
{
if($count==count($followingArray)-1)
{
$sql2 .= "LIKE";
$sql2 .= "%'".$value."'%";
}
else
{
$sql2 .= "LIKE";
$sql2 .= "%'".$value."'%,";
}
++$count;
}
$sql2 .= ")";
I get this error, that says
"trying to get property of non object"
I can't figure out what is going on any suggestions would be much appreciated thank you for your time.
You should not be using LIKE in an IN clause but you do need to comma delimit elements. No need to keep track of the count, either. foreach will cease when the array has been traversed and you can trim off the trailing comma.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE FavorIDs IN (" ;
foreach($followingArray as $value)
{
$sql2 .= "'".$value."', ";
}
$sql2 = rtrim($sql2,',');
$sql2 .= ");";
If this fails, like Gordon says, echo $sql2 and the syntax error will probably be clear.
If you do indeed need to use LIKE and wildcard matching, you could append multiple OR clauses, one for each $value.
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages WHERE " ;
$whereClause = "";
foreach($followingArray as $value)
{
$whereClause .= " OR FavorIDs LIKE '%".$value."%' ";
}
$whereClause = ltrim($whereClause, " OR");
$sql2 .= $whereClause . ";";
UPDATE 1/9/15
I realized there's a bug in this code in that when $followingArray is empty, we'd receive a MySQL syntax error because the query ends with "WHERE". Here's a new version which resolves that bug:
$sql2 = "SELECT * FROM pixacour_pixacourt.UserCaseMessages" ;
if(count($followingArray) >= 1) {
$sql2 .= " WHERE";
}
$whereClause = "";
foreach($followingArray as $value)
{
$whereClause .= " OR FavorIDs LIKE '%".$value."%' ";
}
$whereClause = ltrim($whereClause, " OR");
$sql2 .= $whereClause . ";";

PHP 'Where' query conditional on 'If' 'isset'

I am new to PHP so any help on the following would be really appreciated:
I am trying to run a query with a WHERE condition, but I only want to apply the where condition if the variable has been set (via a radio button).
I basically want to be able to say - if a variable is not set, do not include it in the where condition. The complication is that I will be doing this with 3+ variables...
At its most basic - here is the code I have so far:
if(isset($_POST['category'])){
$category = $_POST['category'];}
if(isset($_POST['brand'])) {
$brand = $_POST['brand'];
}
{
$q = 'SELECT name, category, brand, price, imageurl, purchaselink FROM clothes WHERE category = "'.$_POST['category'].'" AND brand = "'.$_POST['brand'].'"';
[truncated]
Thanks very much in advance!
You can do this with an array, but first of all DO NOT BUILD QUERIES THIS WAY since you'll be vulnerable to SQL injection. Use PDO instead.
The idea is to have a list of suitable conditions:
$conds = [ 'brand', 'category', 'name' ];
$where = [ ]; // Empty array
foreach ($conds as $cond) {
if (!empty($_POST[$cond])) {
$sql = "({$cond} = ?)"; // We use PDO and bound values.
$where[$sql] = $_POST[$cond];
// In *deprecated* MySQL we would use at least
// $sql = "({$cond} = '" . mysql_real_escape_string($_POST[$cond]) . "')";
// $where[$sql] = true;
}
}
// Now we have a list of pairs:
// brand = ? => 'MyBrand',
// name = ? => 'MyName',
if (!empty($where)) {
$sql_string .= ' WHERE (';
$sql_string .= implode( ' AND ', array_keys($where) );
$sql_string .= ')';
}
// $sql_string is now SELECT ... WHERE ( (brand=?) AND (name=?) ... )
// Using the MySQL version, we would have ... WHERE ( (brand='MyBrand') AND ... ) )
// With PDO we PREPARE the query using sql_string
// http://dev.mysql.com/doc/apis-php/en/apis-php-pdo-mysql.html
// http://www.php.net/manual/en/intro.pdo.php
// We need an open PDO connection saved into $pdo
$stmt = $pdo->prepare ($sql_string);
// Then we execute the query.
// Bind the values to array_values($where).
$stmt->execute( array_values($where) );
while ($tuple = $stmt->fetch(PDO::FETCH_ASSOC)) {
...
}
A shorter way, MySQL only (since it does not distinguish between keys and values) would be
$where = [ ]; // empty array()
foreach ($conds as $cond) {
if (empty($_POST[$cond])) {
continue;
}
// THIS IS NOT SECURE. See e.g. http://johnroach.info/2011/02/17/why-mysql_real_escape_string-isnt-enough-to-stop-sql-injection-attacks/
$escaped = mysql_real_escape_string($_POST[$cond]);
$where[] = "({$cond} = '{$escaped}')";
}
$query = "SELECT ...";
if (!empty($where)) {
$query .= " WHERE (" . implode(' AND ', $where) . ")";
}
This approach has the additional advantage that you can have the 'AND' parameterized - the user can choose whether have the conditions ANDed or ORed via a radiobutton:
$and_or = ('OR' == $_POST['andor']) ? ' OR ' : ' AND ';
$query .= " WHERE (" . implode($and_or, $where) . ")";
Note that the actual value of 'andor' is NOT used -- if it is an OR, all well and good, ' OR ' is used. Anything else that might be accidentally sent in a POST by a customer, such as "--; DROP TABLE Students;" , is considered to mean ' AND '.
you have to incluide all inside if(){}
if(isset($_POST['category']) && isset($_POST['brand'])){
$q = 'SELECT name, category, brand, price, imageurl, purchaselink FROM clothes WHERE category = "'.$_POST['category'].'" AND brand = "'.$_POST['brand'].'"';
}
I use this technique to make my filters :
$q = 'SELECT name, category, brand, price, imageurl, purchaselink FROM clothes WHERE 1=1 ';
if(isset($_POST['category'])) $q .= ' AND category ="'.$_POST['category'].'"';
if(isset($_POST['brand'])) $q .= ' AND brand = "'.$_POST['brand'].'"';
// here you can add other filters. :) be happy

Setting up SQL queries with multiple parameters

I need to set up a SQL query with multiple parameters that are being pulled from the URL. So far I can only get it to work with the there is only one item in the URL.
My default query to pull in all the content
$sql = "SELECT ";
$sql .= "* ";
$sql .= "FROM ";
$sql .= "cms_site_content ";
$sql .= "WHERE ";
$sql .= "1";
I then check if anything was passed through the URL and retrieve it.
if (isset($_GET["d"])) {
$d=$_GET["d"];
Inside the if statement, I break the values passed as "d" into separate items
$newD = explode(',',$d);
$countD = count($newD);
foreach($newD as $discipline) {
if ($countD == 1) {
$sql .= " AND";
$sql .= " discipline='".$discipline."'";
}
My problem is getting the SQL to work if there is more than one discipline value. It should read something like this:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value"
however if there's more than one discipline value, it should read:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value OR discipline="value2" OR discipline="value3"
Is there a more efficient way to write this? I can't figure out how to insert the OR into the foreach statement.
Save all discipline values in an array;
$discipline_arr = array();
foreach($newD as $discipline) {
$discipline_arr[] = $discipline;
// by the way, don't forget to escape for sql injection
// mysql_escape_string is the depracated one, u can use that if u have no
// other choice
}
Then in your sql, add them as discipline in ('value1','value2', 'etc ...') condition (that is for strings, for numeric types it would be like discipline in (1,2,3,4, etc)
$sql = " SELECT * FROM cms_site_content WHERE 1 " .
(empty($discipline_arr) ? "" : "and
discipline in ('". implode("','" , $discipline_arr). "') ") ;
Link to escaping
http://tr1.php.net/manual/en/function.mysql-escape-string.php
Assuming the rest of your query is in tact. Simply store all of your discipline values in an array as follows, then feed the $discipline_string to your $sql query:
$discipline_ary = array('option1', 'option2', 'option3');
$discipline_string = "";
for($i=0; $i < count($discipline_ary); $i++){
$discipline_string .= " discipline = '" . $discipline[$i] . "' ";
if($i+1 == count($discipline_ary)){
break;
}else{
$discipline_string .= " OR "
}
}

MySQL error 1064 when performing an SELECT query

I have code like this:
function search_keyword(){
$keyword = trim($_POST['keyword']);
$search_explode = explode(" ", $keyword);
$x = 0;
$sql = " ( SELECT name, id_global_info AS id, body AS body, tag AS tag ,info_type_id AS info_type, \"global_info\" AS mytable FROM global_info WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%' ";}
else {
$sql .= " AND name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= " ( SELECT name, id_person AS id, surname AS body, info AS tag , location AS info_type, \"person\" AS mytable FROM person WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%' ";}
else {
$sql .= " AND name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= "( SELECT name, id_event AS id, body AS body, caffe_id AS tag , date AS info_type, \"event\" AS mytable FROM event WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%' ";}
else {
$sql .= " AND name LIKE '%$each%' ";
}
}
$sql .= " ) UNION ALL ";
$sql .= "( SELECT name, id_caffe AS id, description AS body, adress AS tag, location_id AS info_type, \"caffe\" AS mytable FROM caffe WHERE ";
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%' ";}
else {
$sql .= " AND name LIKE '%$each%' ";
}
}
$sql .= " ) ";
echo $sql;
$q = $this->db->query($sql);
return $q = $q->num_rows() == 0 ? FALSE : $q->result();
}
When I search for exapmle
"mali oglasi"
I get following error:
Error Number: 1064
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'AND name LIKE '%mali%' AND name LIKE '%oglas%' ) UNION ALL (
SELECT name, id_e' at line 1
This is MySQL query it is producing:
( SELECT name, id_global_info AS id, body AS body, tag AS tag ,info_type_id AS info_type, "global_info" AS mytable FROM global_info WHERE name LIKE '%mali%' AND name LIKE '%oglas%' )
UNION ALL
( SELECT name, id_person AS id, surname AS body, info AS tag , location AS info_type, "person" AS mytable FROM person WHERE AND name LIKE '%mali%' AND name LIKE '%oglas%' )
UNION ALL
( SELECT name, id_event AS id, body AS body, caffe_id AS tag , date AS info_type, "event" AS mytable FROM event WHERE AND name LIKE '%mali%' AND name LIKE '%oglas%' )
UNION ALL
( SELECT name, id_caffe AS id, description AS body, adress AS tag, location_id AS info_type, "caffe" AS mytable FROM caffe WHERE AND name LIKE '%mali%' AND name LIKE '%oglas%' )
What seems to be an error?
First thing's first: don't forget to escape your input value. This can be done in your case either on the initial value, or for each iteration of the foreach loop on $each
// If your query() method calls mysql_query()
$keyword = mysql_real_eascape_string(trim($_POST['keyword']));
// Or if query() is mysqli::query()
$keyword = $this->db->real_escape_string(trim($_POST['keyword']));
// Or if this is Codeigniter's API
$keyword = $this->db->escape_like_str(trim($_POST['keyword']));
You need to reset $x at the start of each foreach loop:
// Reset $x to 0 before the start of each of your loops.
$x = 0;
foreach($search_explode as $each){
$x++;
if($x == 1){
$sql .= " name LIKE '%$each%' ";}
else {
$sql .= " AND name LIKE '%$each%' ";
}
}
Note: It is generally advisable to use parameterized queries instead of building the query by concatenation and interpolation. Codeigniter uses ? placeholders for that.
Your query errors reside in the second, third and fourth SELECT statements, as you have WHERE AND name rather than WHERE name

Php Syntax Help

I'm working on a search function, it was working fine four days ago, now it's returning this error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND state = 'AZ '' at line 1
what is the proper syntax for this line?
if($search_state !== "") {
$query .="AND state = '" . $search_state . " ' " ;
the entire portion is:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ORDER BY state ASC ";
if($search_co !== "") {
$query .= "AND name LIKE '%" . $search_co ."%' ";
}
if($search_first !== "") {
$query .= "AND contact LIKE '%" .$search_first."%' ";
}
if($search_last !== "") {
$query .= "AND contact LIKE '%" .$search_last."%' ";
}
if($search_city !== "") {
$query .="AND city = ' " . $search_city . " ' ";
}
if($search_state !== "") {
$query .="AND state = '" . $search_state . " ' " ;
}
You can't put AND conjunctions for your WHERE clause after an ORDER BY. Your ORDER BY clause has to come after the entirety of the WHERE clause.
You need to put the AND statements after the where, and before the sort_by.
Move the sort_by to the end of the php (append to the query string), and it should work.
Try this:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ";
if($search_co !== "") {
$query .= "AND name LIKE '%".$search_co."%' ";
}
if($search_first !== "") {
$query .= "AND contact LIKE '%".$search_first."%' ";
}
if($search_last !== "") {
$query .= "AND contact LIKE '%".$search_last."%' ";
}
if($search_city !== "") {
$query .= "AND city = '".$search_city."' ";
}
if($search_state !== "") {
$query .= "AND state = '". $search_state."' " ;
}
$query.= "ORDER BY state ASC"
As was said by others, your order by statement has to come last. Also, you had spaces surrounding the city name in the city = portion of the query. While this is valid SQL syntax, it's only going to return results where the city name is surrounded by spaces. I'm guessing that's not what you wanted.
Also, you may want to add some more fields to your order by. Right now, it will order by state, but will records come back randomly by state. Maybe something like
$query.= "ORDER BY state, city, name, id"
Finally, just FYI, if you're not carefully sanitizing your search inputs, this approach is susceptible to SQL Injection.
Also, you seem to have spaces between the single and double quotes which will make the query like this: AND state = ' AZ ' which is probably not what you want. You can also avoid the additional quotes and concatenations in PHP by using this syntax:
$query .= " AND state = '$search_state' ";
Of course I have to mention that you should sanitize your inputs to protect against SQL injection.
The WHERE part comes before the AND's in your code, which is wrong. This is what you want
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ";
if($search_co !== "") {
$query .= "AND name LIKE '%" . $search_co ."%' ";
}
...
$query .= " ORDER BY state ASC ";
Also, for completeness sake, you could make the code a bit easier to read:
$query .= "AND name LIKE '%$search_co%' ";
because your string is double quoted
I think this might work:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new ";
$conditions = array();
if(!empty($search_co)) {
$conditions[] = "name LIKE '%" . $search_co ."%' ";
}
if(!empty($search_first)) {
$conditions[] = "contact LIKE '%" .$search_first."%' ";
}
if(!empty($search_last)) {
$conditions[] = "contact LIKE '%" .$search_last."%' ";
}
if(!empty($search_city)) {
$conditions[] = "city = '" . $search_city . "' ";
}
if(!empty($search_state)) {
$conditions[] = "state = '" . $search_state . "' " ;
}
if (count($conditions) > 0) {
$query .= " WHERE " . implode(' AND ', $conditions);
}
$query .= " ORDER BY state ASC";
Edit: The original version used empty, it should have been !empty. It's fixed now.
Edit 2: This also assumes you've already sanitized the variables using mysql_real_escape_string or similar.
Note that ORDER BY has to be after the WHERE clauses.
implode takes an array and turns it into a string with the specified string between the elements. So, given:
$myArray = array('A', 'B', 'C');
you can do
$myString = implode(' and ', $myArray);
which would put "A and B and C" into $myString.

Categories