Creating a query using loop for the WHERE clause - php

I'm trying to build a MySQL query using a loop for the where clause. I have a solution, but I feel like there should be a better solution. My code is as follows
$query = 'SELECT * FROM `t1` WHERE';
$names = ['John','Steve','Robert'];
foreach($names as $name){
$query .= " `name` = '$name` OR";
}
echo $query;
In this case query ends with "OR" that makes it invalid. The solution I have is to trim it using
echo rtrim($query," OR");
I feel like there should be a cleaner way of doing it. Any suggestions?

You can fix your query using where in and join. In your case it should be :
$query = 'SELECT * FROM `t1` WHERE name IN (\'' . join($names,'\',\'') . '\')';
Note: join is aliases for implode. It help code readability. Be careful with SQL Injection. You might want to validate the input or using PDO.

You could push the tests to an array and then implode them with OR:
$query = 'SELECT * FROM `t1` WHERE';
$names = ['John','Steve','Robert'];
$tests = array();
foreach($names as $name){
$tests[] = "`name` = '$name'";
}
$query .= implode(' OR ', $tests);
Demo on 3v4l.org

I do what you do in my applications, just becareful with more complicated WHERE clauses in the future.
For example, if your array is empty, you should omit "WHERE"
$query = 'SELECT * FROM `t1`';
if ($names) $query .= " WHERE";
if your where clause will have AND you should give attention to that AND is having higher precedence than OR and to use the proper brackets ()
In the code example you provided you can also do this to avoid rtrim
$names = ['John','Steve','Robert'];
foreach ($names as &$name) $name = "'$name'";
unset($name);
$query = 'SELECT * FROM `t1` WHERE `name` IN (' . implode(', ', $names) . ') ';

Related

mysql dynamic queries without clause where

In the following example there is a base query. Other parameters can be dynamically added to complete the query.
However, my base query has no clause WHERE.
What is the best way to deal with it.
If I use in the base query, for example, WHERE 1 = 1, it seems to solve, but I have some doubts that is a correct solution.
$myQuery = "SELECT fr.oranges, fr.aplles, fr.bananas,
FROM fruits fr
LEFT JOIN countrys ct ON fr.id_fruit = ct.id_fruit";
if(!empty($countrys){
$myQuery .= " AND countrys = ? ";
}
if(!empty($sellers){
$myQuery .= " AND seller = ? ";
}
$myQuery .=" GROUP BY fr.id_fruit ORDER BY fr.fruit ASC";
Edited: I fixed a writing gap from $empty to empty.
The WHERE 1=1 is a simplistic hack that works well because it simplifies your code. There is a great post here which explains the performance implications of WHERE 1=1. The general consensus is it will have no effect on performance.
Also, slight note ($empty) is probably not a function you've defined. I think you want empty(). You could write it like this:
$myQuery = "SELECT fr.oranges, fr.aplles, fr.bananas,
FROM fruits fr
LEFT JOIN countrys ct ON fr.id_fruit = ct.id_fruit";
$where = [];
if(!empty($countrys){
$where[] = "countrys = ?";
}
if(!empty($sellers){
$where[] = "seller = ?";
}
if (!empty($where)) {
$myQuery .= " WHERE " . implode(" AND ", $where);
}
$myQuery .= " GROUP BY fr.id_fruit ORDER BY fr.fruit ASC";
You can use an array to control your SQL like this:
$where = [];
if(!$empty($countrys){
$where[] = " countrys = ? ";
}
if(!$empty($sellers){
$where[] = " seller = ? ";
}
if(count($where) > 0) {
$myQuery .= " WHERE ".implode('AND', $where);
}

How to debug the concatenation of a SQL query in PHP?

There's something with my query, but I cannot manage to find what.
$keys = array_keys($fields);
$values = array_values($fields);
$sql = "UPDATE " .$table. " SET " .implode("`, `", $keys) ."='".implode("', '", $values) . "' WHERE id={$id}";
And it shows as : UPDATE users SET name, password'Rick is vets', 'sdfg' WHERE id=5
But it has to show as : UPDATE users SET name = 'Rick is vets', password='sdfg' WHERE id=5
Try looping through the $fields array to create an update string like this:
$update_string='';
foreach ($fields as $key=>$value)
{
$update_string .= $key."='$value', ";
}
Then remove the last comma character from the string using rtrim() function:
$update_string = rtrim($update_string, ", ");
Then your query becomes:
$sql = "UPDATE " .$table. " SET " .$update_string. " WHERE id={$id}";
This is just to illustrate the concept since your code might still be
open to SQL injection attacks, in which case you should use prepared
statement.
$setString='';
foreach($fields as $k=>$v){
$setString .=$k." = '".$v."', ";
}
$setString=rtrim($setString,', ');
include $setString in query

PHP: How to pass multiple values to SELECT query

I am new to PHP and hope someone can help me with this.
I currently use the below lines to retrieve a value from a db and to output it as an array with the item's ID and value which works as intended.
Now I would need to do the same for multiple items so my input ($tID) would be an array containing several IDs instead of just a single ID and I would need the query to do an OR search for each of these IDs.
I was thinking of using a foreach loop for this to append " OR " to each of the IDs but am not sure if this is the right way to go - I know the below is not working, just wanted to show my thoughts here.
Can someone help me with this and tell me how to best approach this ?
My current PHP:
$content = "";
$languageFrm = $_POST["languageFrm"];
$tID = $_POST["tID"];
$stmt = $conn->prepare("SELECT tID, " . $languageFrm . " FROM TranslationsMain WHERE tID = ? ORDER BY sortOrder, " . $languageFrm);
$stmt->bind_param("s", $tID);
$stmt->execute();
$result = $stmt->get_result();
while($arr = $result->fetch_assoc()){
$content[] = array("ID" => $arr["tID"], "translation" => $arr[$languageFrm]);
}
My thought:
foreach($tID as $ID){
$ID . " OR ";
}
Many thanks for any help,
Mike
There are two approaches, assuming $tID is an array of IDs
Using MySQL IN() clause
This will work also when $tID is not an array, but a single scalar value.
$tID = array_map('intval', (array)$tID); // prevent SQLInjection
if(!empty($tID)) {
$query .= ' WHERE tID IN(' . implode(',', $tId) . ')';
} else {
$query .= ' WHERE 0 = 1';
}
Using OR clause, as you suggested
A bit more complicated scenario.
$conds = array();
foreach($tID as $ID) {
$conds[] = 'tID = ' . intval($ID);
}
if(!empty($conds)) {
$query .= ' WHERE (' . implode(' OR ', $conds) . ')';
} else {
$query .= ' WHERE 0 = 1';
}
As per above conditions you can try with implode();
implode($tID,' OR ');
You can also use IN condition instead of OR something like this.
implode($tID,' , ');

MySQL IN for strings

I have an array $friends and I used $friend_new = join(',',$friends ); to get name1,name2,name3.
But when I use this query I got error:
$query = mysqli_query($connect_db, "SELECT * FROM post WHERE name IN ($friend_new )");
Does anyone know where the problem is?
You should use implode("','", $friends) and IN ('$friends_new') as these are string values.
Your code is vulnerable to injection. You should use properly parameterized queries with PDO / mysqli
Your list has to look like:
... IN ('friend1','friend2','friend3')
If you have an array of friends such as:
$friends = array("friend1","friend2","friend3");
You can use implode to prepare for use with an IN:
$friend_new = "'" . implode("','", $friends) . "'";
Finally,
SELECT * FROM post WHERE name IN ($friend_new)
The way you do it the individual strings won't be quoted, and that causes the error. As join allows you to specify a "glue" longer than 1 character you can do as follows:
$query = mysqli_query($connect_db,
"SELECT * FROM post " .
"WHERE name IN ('".join("', '", $friends)."') ";
or
$friend_new = join("', '", $friends);
$query = mysqli_query($connect_db,
"SELECT * FROM post " .
"WHERE name IN ('$friend_new') ";
that is, have join write the intermediate ', ' , and surround with ''

how can I avoid to many OR statements in a mysql query?

I am writing a code, where I have to produce a query with many OR statements, and I think there is a more comfortable way to this than:
foreach ($plz as &$value) {
if (empty($i)) {
$query = "WHERE plz='$value'";
} else {
$query = "$query OR plz='$value'";
}
$i++;
}
$sql = mysql_query("SELECT * FROM table $query");
while ($data = mysql_fetch_array($sql)) {
//do something
}
If you have multiple values a column may take, just connect them using the IN operator:
Instead of writing
... WHERE col=1 OR col=2 OR col=3
just write
... WHERE col IN (1,2,3)
To collect all entries in PHP, use an array and implode() later on:
// collecting values
$vals = array();
$vals[] = 1;
$vals[] = 2;
// ...
// add them to your query
$query .= ' WHERE col IN ( ' . implode( ',', $vals ) . ')';
// execute the query ...
In case your values are not integer, but need to be enclosed in apostrophes within the query, insert them that way into the array in the first place:
$vals[] = "'my string value'";
You're looking for ;
SELECT * FROM table WHERE plz in ('value1', 'value2', 'value3')
Be aware of SQL injections...
If the column plz is INT type, and all $plz are also integers, then:
$query = 'WHERE plz IN( ' . implode(',', $plz) . ')';
would work. Otherwise, trying this might work(not tested):
$query = 'WHERE plz IN( \'' . implode("','", $plz) . '\')';

Categories