This question already has answers here:
MySQLi Bind Param with an array for IN [duplicate]
(2 answers)
Closed 4 years ago.
I have this select:
$stmt = $mysqli->prepare("select following from following where user =? and block=0");
$stmt->bind_param('i', $user);
$stmt->execute();
$stmt->bind_result($followers);
$stmt->fetch();
$stmt->close();
I'd like to use $followers in another mysql conection:
select... from ... where (p.user in (?))
in this ? I'd like to place the $followers variable in mysql in format. (1,5,7,2).
Any ideas how to convert the bind_result $followers into this mysql in format?
One way to accomplish this would be to create another string variable and append the result of $followers in a while loop.
I typically work in procedural style, and I am assuming that your statement returns multiple rows into $followers:
$sql_in_string = ''; // initialize string variable as blank
while (mysqli_stmt_fetch($stmt)){
$sql_in_string = $sql_in_string . $followers . "," ; // append value + comma
}
$sql_in_string = rtrim($sql_in_string,","); // remove the final comma
At this point, $sql_in_string should have your values as "1,2,3" format and then you can bind that parameter to your next query.
Related
This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
If you create a variable inside a if statement is it available outside the if statement?
(4 answers)
How to replace "if" statement with a ternary operator ( ? : )?
(16 answers)
If variable equals value php [duplicate]
(4 answers)
Closed 2 years ago.
There are a lot of examples on SO of using str_replace to modify a query that uses variables in MYSQL but I can't find one that solves my problem.
I have the following legacy query that I'm debugging written in PHP and MySQL.
Somewhat simplified it is:
$sql = "SELECT * from MOVIES WHERE cat = '$cat'";
In the event that cat has a certain value, say, "action" I want to check for "adventure";
Let's say you start with query:
$cat = "action";
$sql = "SELECT * FROM MOVIES WHERE cat='$cat'";
I'm trying to modify the query with:
$needle = "cat=".$cat;
$altcat = "adventure";
$altwhere = "cat=".altcat;
$sql = str_replace($needle,$altwhere,$sql); //NOTHING GETS REPLACED...NOT MATCHING Needle
How can I do this? I'm thinking the problem has something to do with use of spaces or apostrophes in the sql string but can't get it to work.
Thanks for any suggestions.
You want to replace "cat='".$cat."'" with "cat='adventure'", not "cat=".$cat with "cat=adventure".
(Though you are inconsistent in saying if there are spaces around the =.)
But you should not do this and should use a placeholder instead.
I would not try to do string substitution on the SQL query. Instead, just use query parameters.
$cat = 'action'; // suppose this is the input to your program
$sql = "SELECT * from MOVIES WHERE cat = ?";
if ($cat == 'action') {
$cat = 'adventure';
}
$stmt = $db->prepare($sql);
$stmt->execute( [ $cat ] );
This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
Closed 11 months ago.
I'm trying to create a select query with dynamic where clause and dynamic parameters but I always get error :
Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
Which I sincerely do not understand since it seems the count is alright. So this is what the code really looks like in its rude format. I can't see what I'm doing wrong.
//get variables
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
//convert string to array
$socialArray = explode(',', $mediaArray)
//declare some variables to be used later
$andwhere = '';
$bp = '';
$socialmarray = ''
//get every value from array of social media
foreach($socialArray as $socialmedia){
$socialmarray .=$socialmedia.',';
$andwhere .= " AND socialmedianame=?";
$bp .='s';
}
//test strings
echo $wheres = $andwhere;//AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?
echo $bip = $bp.'s';//ssss
echo $validarayy = rtrim($socialmarray,',');//Facebook,Twitter,Twitch
//select query
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$selectquery->execute();
$resultquery = $selectquery->get_result();
Because:
You are using user-supplied data, you must assume that your query is vulnerable to a malicious injection attack and
the amount of data that is to be built into the query is variable/indefinite and
you are only writing conditional checks on a single table column
You should use a prepared statement and merge all of the WHERE clause logic into a single IN statement.
Building this dynamic prepared statement is more convoluted (in terms of syntax) than using pdo, but it doesn't mean that you need to abandon mysqli simply because of this task.
$mediaArray ='Facebook,Twitter,Twitch,';
$otherMedia = 'House';
$media = array_unique(explode(',', $mediaArray . $otherMedia));
$count = count($media);
$conn = new mysqli("localhost", "root", "", "myDB");
$sql = "SELECT * FROM mediaservices";
if ($count) {
$stmt = $conn->prepare("$sql WHERE socialmedianame IN (" . implode(',', array_fill(0, $count, '?')) . ")");
$stmt->bind_param(str_repeat('s', $count), ...$media);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $conn->query($sql);
}
foreach ($result as $row) {
// access values like $row['socialmedianame']
}
For anyone looking for similar dynamic querying techniques:
SELECT with dynamic number of LIKE conditions
INSERT dynamic number of rows with one execute() call
In your query:
$selectquery = $conn->prepare("select * from mediaservices where socialmedianame=? $wheres");
The ? represents one parameter to pass in, and the evaluation of $wheres adds another three, giving you four total parameters.
bind_param() should take a string representing the types of the variables to insert as the first parameter, and the variables themselves as the subsequent parameters.
In your bind:
$selectquery->bind_param("$bip",$otherMedia,$validarayy);
$bip evaluates to ssss and $otherMedia is a single string ("House"). You might expect $validarayy to be three strings, but rtrim() returns a string. Thus, it is only one string ("Facebook,Twitter,Twitch"). You pass through two variables when the query is expecting four:
$conn->prepare("select * from mediaservices where socialmedianame=House AND socialmedianame=Facebook,Twitter,Twitch AND socialmedianame=? AND socialmedianame=? AND socialmedianame=?"
To correct this, you'll want to convert $validarayy back to an array, and use the index for the various inputs:
$socialmarray2 = explode(',', $validarayy);
$selectquery->bind_param("$bip", $otherMedia, $socialmarray2[0], $socialmarray2[1], $socialmarray2[2]);
Also note that your sample code has a few missing semicolons; you'll need to fix these in order for your code to work correctly.
This can be seen working here.
Finally, note that even if you were to split the three strings out correctly, the selection of ... AND socialmedianame=Facebook AND socialmedianame=Twitter AND socialmedianame=Twitch will never match any results; socialmedianame can only contain one value. You're probably looking to substitute your AND statements with OR statements.
This question already has answers here:
PHP - Using PDO with IN clause array
(9 answers)
Closed 5 years ago.
I have this code:
$Array=array();
array_push($Array,"Email1","Email2");
$Array=implode("','",$Array);
$Array="'$Array'";
echo "$Array" //Will output 'Email1','Email2'
$Check=$connection->prepare("SELECT ID FROM USERS WHERE EMAIL IN(:Array)");
$Check->execute(array(
':Array' => $Array,
));
This query won't work but if I write:
$Check=$connection->prepare("SELECT ID FROM USERS WHERE EMAIL IN('Email1','Email2')");
$Check->execute(array(
':Array' => $Array,
));
This works, but I won't bind the array to avoid SQL Injection.
How can I fix it?
You don't want to bind the imploded list as one element but rather each of the values individually using ? so the end of the statement would be WHERE EMAIL IN (?,?):
$values = ["Email1","Email2"];
# This should give you ?,?
$bindstr = implode(",",array_fill(0,count($values),'?'));
$query = $connection->prepare("SELECT ID FROM USERS WHERE EMAIL IN({$bindstr})");
# Use the raw values individually in the execute
$query->execute($values);
Hopefully that should get results back you are looking for.
This question already has answers here:
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 2 years ago.
I've been trying to figure this out.
$insertSql = 'INSERT INTO table (id,date,name,numFarts) VALUES (?,?,?,?)';
$values = (1,'0000-00-00 00:00:00','Bob',5);
$bind_param_str = ('issi');
if ($stmt = $db->prepare ($insertSql)) { // $inserSql is a pre-writted sql insert
$stmt->bind_param($bind_param_str,$values);
$stmt->execute();
$stmt->close();
}
This doesn't work, but I can't think of any other way to pass $values into bind_param()
Any ideas?
For any function that you need to pass an array as the argument/s you can use call_user_func_array.
In this example:
array_unshift($values,$bind_param_str);
call_user_func_array(array($stmt,'bind_param'),$values);
Don't ask me why you need array($stmt,'bind_param') instead of $stmt->bind_param. Has something to do with the syntax of -> I'm sure.
The clean solution (PHP5.6+) :
$stmt->bind_param($bind_param_str, ...$values);
This question already has answers here:
How to fetch all in assoc array from a prepared statement?
(4 answers)
Closed 2 years ago.
I want to put the result of a mysqli prepared statement into an array and return the array for use in another page.
The code is presented below.
function getPermission($mysqli , $email) {
if ($stmt = $mysqli->prepare("SELECT m.email , g.permission
FROM members m
INNER JOIN members_groups q ON m.member_id = q.member_id
INNER JOIN groups g on q.group_id = g.group_id
WHERE email = ?"))
{
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_email, $user_perms);
while ($stmt->fetch()) {
echo ' ID: '.$user_email; //prints the results.
}
}
}
I want to place the query results into an array and return the array.
Note: Am using a wamp server with php and mysql in windows 7. I tried to use the $stmt->getresults method, but it returns nothing.
You could try to store it in an array, one by one, in your loop:
$results = array();
while ($stmt->fetch()) {
$results[] = array(
"email" => $user_email,
"perms" => $user_perms
);
}
return $results;
If you need this array in another file, where you include this function, this will work, but if you need it in another request, PHP will have to run this code again to have the array filled.
If you need this array during the session, then consider putting the result in a session variable:
$_SESSION['myarray'] = $results;
Then in the function, first check if the above session variable is set, and if so, immediately return that value. Only when it is not yet set, you perform the rest of the function.