This question already has answers here:
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 1 year ago.
I am trying to sum a colomn based on the IDs selected from a table that i put in a array. For some reasom only the first ID is used in the Where clausule. When I echo the variable all the ids are there. What am i doing wrong?
$counttheid = array();
$stmt3 = $mysqli->prepare("SELECT
id
FROM account
WHERE level <= '5' AND door = ? AND `group_name` = ? AND betaald = 'Yes'");
$stmt3->bind_param("ss",$usernamesession,$groupname);
$stmt3->execute();
$result3 = $stmt3->get_result(); //only works when nd_mysli is set on the server!
while ($rowid = $result3->fetch_assoc())
{
$counttheid[] = $rowid['id'];
$countid = implode(',', $counttheid); // contains all the ids !!
}
$sql = "SELECT SUM(mobcash) AS totalcash FROM account WHERE id IN (?)
";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i",$countid);
$stmt->execute();
$stmt->bind_result($row['totalcash']);
while($stmt->fetch()) $sumcash = $row['totalcash'];
echo $sumcash; // Somhow only the sum of the first ID of the array !!
echo $countid;// all the ids from the array !!
Not only for the in, but the number of bind parameters will need to match as well.
Try with this example for the code from the while to the execute:
while ($rowid = $result3->fetch_assoc())
{
$counttheid[] = $rowid['id'];
// $countid = implode(',', $counttheid); // contains all the ids !!
}
$in = str_repeat('?,', count($counttheid) - 1) . '?';
$types = str_repeat('i', count($counttheid));
$sql = "SELECT SUM(mobcash) AS totalcash FROM account WHERE id IN ($in)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param($types, ...$counttheid);
$stmt->execute();
At the bind_param, the part with ...$counttheid, the ... portion is the argument unpacking operator.
I have a SQL query that is based on user input.
However, in the table, theres a "-1" at the end of every word that you search for.
For example if you want to get the sql result of car, it's actually named car-1 in the database, but the user should only be able to search for car.
This is how its setup:
$sql = "SELECT * FROM that WHERE this = ?";
$stmt = $conn->prepare($sql);
$search_query = $_POST['this'];
$stmt->bind_param('s', $search_query);
$stmt->execute();
$result = $stmt->get_result();
What I want, is that the select query should be like:
$sql = "SELECT * FROM that WHERE this = ? + '-1'";
But ^^ doesn't work.
$sql = "SELECT * FROM test WHERE NAME='car' & -1";
test = that
NAME= table name
'car' = this
Why don't you just concat -1 to search_query :
$sql = "SELECT * FROM that WHERE this = ?";
$stmt = $conn->prepare($sql);
$search_query = $_POST['this'];
$stmt->bind_param('s', $search_query.'-1');
$stmt->execute();
$result = $stmt->get_result();
Using MySQL:
$sql = "SELECT * FROM that WHERE this = CONCAT(?, '-1')";
Using PHP:
$stmt->bind_param('s', $search_query . "-1");
I would like to use name placeholder to pass the value of an array to a select statement, such as:
$keywords=("word1", "word2", etc);
$sql = "SELECT * FROM TABLE WHERE name LIKE :word1 AND name LIKE :word2 etc"
Below is the script that I am working on:
$symptoms=$_POST['search'];
$keywords = preg_split('/[\s]+/', $symptoms);
$totalKeywords = count($keywords);
$sql = "SELECT * FROM TABLE_3 WHERE MATCH (symptoms) AGAINST (:symptoms) ";
$like_placeholder = implode(' AND ', array_fill(0, $totalKeywords, 'symptoms LIKE ?'));
$sql .= " AND ({$like_placeholder})"; // build the query with placeholders
// prep input
$where_keywords = array_map(function($value) {
return "%{$value}%";
}, $keywords);
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':symptoms', $symptoms);
$stmt->execute([$_POST['search']]);
$stmt->execute($keywords);
$results = $stmt->fetchAll();
You can't use both named and question-mark placeholders in the same query. Change the :symptoms placeholder to ? and insert $symptoms at the beginning of your $keywords array.
You're never using $where_keywords. You can concatenate the % wildcard in the SQL code itself.
$symptoms=$_POST['search'];
$keywords = preg_split('/[\s]+/', $symptoms);
$totalKeywords = count($keywords);
$sql = "SELECT * FROM TABLE_3 WHERE MATCH (symptoms) AGAINST (?) ";
$like_placeholder = implode(' AND ', array_fill(0, $totalKeywords, "symptoms LIKE CONCAT('%', ?, '%')"));
$sql .= " AND ({$like_placeholder})"; // build the query with placeholders
$stmt = $pdo->prepare($sql);
array_unshift($keywords, $symptoms);
$stmt->execute($keywords);
$results = $stmt->fetchAll();
I want to search for some username in my database like this->
$skip = $_POST['username'];
$_SESSION['skip_user'] = array();
array_push($_SESSION['skip_user'],$skip);
$str = $_SESSION['skip_user'];
$string = rtrim(implode(',', $str), ',');
Now string variable looks like "name1, name2, name3";
mysqli_query($db, "SELECT * FROM users WHERE username in ({$string}) ORDER BY id DESC");
This fetches the users but i don't want these users. I mean is there any query where i can i write WHERE username !in ({$string})!
get all users except "name1, name2, name3" these users
Now after adding NOT IN I'm receiving error
mysqli_query($db, "SELECT * FROM users WHERE username NOT IN ({$string}) ORDER BY id DESC")or die(mysqli_error($db)); php is giving error Unknown column 'name1' in 'where clause'
Try NOT IN in the SQL query.
First though try to add quotes to the values you are trying in the NOT IN part of the sql query.
$str = '';
foreach ($_SESSION['skip_user'] AS $word) {
$str .= "'$word',";
}
$str = rtrim($str, ',');
Then use this $str in your query. Also, try to make a habit out of using `` for column names, like this:
SELECT `SOMETHING` FROM `TABLE_NAME` WHERE <CONDITION>
I hope that helps!
You should use NOT IN to exclude certain values.
mysqli_query($db, "SELECT * FROM users WHERE username NOT IN ('name1', 'name2') ORDER BY id DESC");
yep, just type "not" instead of "!"
select * from table where junk not in ('item1', 'item2', 'item3');
1) You have a few other problems though you're not adding quotes to your implode:
// you need quotes here
$string = implode("','", $str);
// And here
mysqli_query($db, "SELECT * FROM users WHERE username in ('{$string}') ORDER BY id DESC");
However, this is what you should really be doing.
2) You should bind your parameters instead as you're open to SQL injection:
$params = array();
$params[0] = "";
$sql = "SELECT * FROM users WHERE username NOT IN (";
foreach($str as $s){
$params[0] .= "s";
array_push($params, $s);
$sql .= "?, ";
}
$sql = rtrim($sql, " ,").") ORDER BY id DESC";
$stmt = $conn->prepare($sql);
// this is the same as doing: $stmt->bind_param('s', $param);
call_user_func_array(array($stmt, 'bind_param'), $params);
// execute and get results
$stmt->execute();
I have a a page that appends different parameters to the URL that are used for the query.
For example
http://www.example.com/search.php?category=Schools&country[]=Belgium&country[]=Czech+Republic
My code is like this
if(isset($_GET['country'])){
$cties = "'" . implode("','", $_GET['country']) . "'";
}
else {
$cties = "'Albania','Andorra','Austria','Belarus','Belgium','Bosnia & Herzegovina','Bulgaria','Croatia','Czech Republic','Denmark','Estonia','Faroe Islands','Finland','France','Germany','Gibraltar','Great Britain','Greece','Hungary','Iceland','Ireland','Isle of Man','Italy','Latvia','Liechtenstein','Lithuania','Luxembourg','Macedonia','Malta','Moldova','Monaco','Montenegro','Netherlands','Norway','Poland','Portugal','Serbia','Romania','San Marino','Slovakia','Slovenia','Spain','Sweden','Switzerland','Ukraine','United Kingdom'";
}
if(isset($_GET['category'])){
$cat = $_GET['category'];
}
else{
$cat = " ";
}
try{
// create the Prepared Statement
$stmt = $con->prepare("SELECT * FROM MyTable
WHERE MyDate >= DATE(NOW())
AND (Category=:cat or '' = :cat)
AND Country IN ($cties)
ORDER BY MyDate ASC");
$stmt->bindValue(':cat', $cat, PDO::PARAM_STR);
$stmt->execute();
I was wondering if this query is secure and if not, what I am doing wrong.
Thanks in advance!
I finally got it (thanks to Your Common Sense):
if(isset($_GET['country'])){
$arr = $_GET['country'];
}
else {
$arr = array('Albania','Andorra','Austria','Belarus','Belgium','Bosnia & Herzegovina','Bulgaria','Croatia','Czech Republic','Denmark','Estonia','Faroe Islands','Finland','France','Germany','Gibraltar','Great Britain','Greece','Hungary','Iceland','Ireland','Isle of Man','Italy','Latvia','Liechtenstein','Lithuania','Luxembourg','Macedonia','Malta','Moldova','Monaco','Montenegro','Netherlands','Norway','Poland','Portugal','Serbia','Romania','San Marino','Slovakia','Slovenia','Spain','Sweden','Switzerland','Ukraine','United Kingdom');
}
if(isset($_GET['category'])){
$cat = $_GET['category'];
}
else{
$cat = " ";
}
// create the Prepared Statement
$in = str_repeat('?,', count($arr) - 1) . '?';
$sql = "SELECT * FROM MyTable WHERE MyDate >= DATE(NOW())
AND Country IN ($in)
AND (Category=? or '' = ?)
ORDER BY MyDate ASC";
$stmt = $con->prepare($sql);
$arr[] = $cat; // adding category to array
$arr[] = $cat; // we need it twice here
// finally - execute
$stmt->execute($arr);
Yeah, Now I see your problem. Well, PDO is not too convenient a library for such a task. So, first of all I'll show you how it can be done with my own library:
$sql = "SELECT * FROM MyTable WHERE MyDate >= CURDATE()
AND (Category=?s or '' = ?s)
AND Country IN (?a)
ORDER BY MyDate ASC"
$data = $db->getAll($sql, $cat, $cat, $_GET['country']);
But I quite realize that you all so inclined to familiar methods. Well, let's elaborate with ugly PDO
First of all, what is the goal? The goal is
to create the query that contains placeholders for all the data. I'll stick to positional placeholders as they are easier to implement.
To create an array with all the variables that have to be bound to placeholders
It seems we need two placeholders for category and some unknown number fro cities. All right, this line will create a string of placeholders:
$in = str_repeat('?,', count($arr) - 1) . '?';
which we are going to insert into query.
// $arr is array with all the vars to bind. at the moment it contains cities only
$arr = $_GET['country'];
// creating string of ?s
$in = str_repeat('?,', count($arr) - 1) . '?';
// building query
$sql = "SELECT * FROM MyTable WHERE MyDate >= DATE(NOW())
AND Country IN ($in)
AND (Category=? or '' = ?)
ORDER BY MyDate ASC";
$stm = $db->prepare($sql);
$arr[] = $_GET['category']; // adding category to array
$arr[] = $_GET['category']; // we need it twice here
// finally - execute
$stm->execute($arr);
$data = $stm->fetchAll();
No, the SQL code could be injected in the $_GET['country'] parameter. You don't escape it anywhere.
See PHP PDO: Can I bind an array to an IN() condition?