Using multiple parameters in PHP PDO statement [duplicate] - php

This question already has answers here:
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 1 year ago.
I have the following statement set up. I have replaces a long list of columns with * to make this more readable. FYI - I already know that there are questions similar to this. They use SINGLE select statements with a SINGLE parameter. Somehow this is different.
$sql = <<<EOM
SELECT *
FROM table1
WHERE StreetName like '%:StreetName_Coml%'
UNION
SELECT *
FROM table2
WHERE StreetName like '%:StreetName_Coms%'
UNION
SELECT *
FROM table3
WHERE StreetName like '%:StreetName_Farm%'
UNION
SELECT *
FROM table4
WHERE StreetName like '%:StreetName_Land%';
EOM;
$p = $db->prepare($sql);
$StreetName = 'tree'
$p->bindValue(':StreetName_Coml', $StreetName);
$p->bindValue(':StreetName_Coms', $StreetName);
$p->bindValue(':StreetName_Farm', $StreetName);
$p->bindValue(':StreetName_Land', $StreetName);
$p->execute();
$data = $p->fetchAll(PDO::FETCH_ASSOC);
The query runs, with no PHP errors. But I am getting no results back. I should be getting back 100's of rows. When I run the same query in my database browser I get 100's of rows. There is something in how the parameters are being bound that is not working.
I have tried the following:
bindParam instead of bindValue
moving the '%' from the SQL statement and into $StreetName. So instead of 'tree' it is '%tree%'
using a CONCAT statement like "WHERE StreetName like CONCAT('%',:StreetName_Land,'%')
and various mix and matching of the above.
What am I missing?

Put the percent signs in the bind, so your SQL is like this, unqouted:
WHERE StreetName like :StreetName
And then your binds are like this:
$p->bindValue(':StreetName', '%' . $StreetName . '%');

Related

sql prepared statment don't work with WHERE <column> IN clause [duplicate]

This question already has answers here:
PHP - Using PDO with IN clause array
(9 answers)
MySQLi prepared statements with IN operator [duplicate]
(1 answer)
Closed 3 years ago.
So I have this sql preparted statment:
SELECT carName, modelName
FROM cars
INNER JOIN model ON cars.idCar = model.idCar
WHERE carName IN (?)`
$input = " 'toyota','honda' "
I am trying to put this into the sql statment, but it gives zero rows out. I have tried the query in phpMyAdmin and there it works all fine. Anyone know the problem?
You need one parameter per value in the IN list. If you pass a single parameter, it is interpreted as a unique string that contains a comma, which is not what you want (and you end up with no match, since none of the names in the table matches this value).
So for two parameters:
SELECT carName, modelName
FROM cars
INNER JOIN model ON cars.idCar = model.idCar WHERE carName IN (?, ?);
The IN clause takes multiple arguments and each parameter can only take on one value. So to automate the process of inserting multiple parameters in this statement you could use something like the following:
/* Execute a prepared statement using an array of values for an IN clause */
$params = ['toyota', 'honda'];
/* Create a string for the parameter placeholders filled to the number of params */
$place_holders = implode(',', array_fill(0, count($params), '?'));
/*
This prepares the statement with enough unnamed placeholders for every value
in our $params array. The values of the $params array are then bound to the
placeholders in the prepared statement when the statement is executed.
This is not the same thing as using PDOStatement::bindParam() since this
requires a reference to the variable. PDOStatement::execute() only binds
by value instead.
*/
$st = $db->prepare("SELECT carName, modelName FROM cars WHERE carName IN ($place_holders)");
$st->execute($params);

How to use bindValue with LIKE operator in SQL query? [duplicate]

This question already has answers here:
pdo prepared statements with wildcards
(2 answers)
How to bind LIKE values using the PDO extension?
(7 answers)
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
PHP PDO & SQL Search wildcard bind parameters
(1 answer)
Using named parameters with PDO for LIKE
(1 answer)
Closed 4 years ago.
I've been trying to replace the value in '%:value%' when I use the LIKE operator in my query.
I have also tried using CONCAT() but that didnt work either.
$query = "SELECT *
FROM books
WHERE title LIKE '%:title%'";
...
...
statement->bindValue(':title', $title, PDO::PARAM_STR);
:title should be replaced with the variable $title but it doesnt. The query is working fine but the :title just doesnt get replaced.
You probably want :
$query = "SELECT *
FROM books
WHERE title LIKE CONCAT( '%', :title, '%')";
...
...
statement->bindValue(':title', $title, PDO::PARAM_STR);
The bind parameter should be used as a litteral string. CONCAT can be used to concatenate the parameter with percent signs on both ends.
Did you try using concat() like this?
SELECT *
FROM books
WHERE title LIKE CONCAT('%', :title, '%')

get result in the same format as mysql in? [duplicate]

This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 11 months ago.
I have a select where I need to scan a table to get results:
where (p.user in (select f from fl where user =? and block=0))
This table is a big table with more than 1 million rows. And it is taking a while to read. I need to read it all the time, so I was thinking I could read it once and then just use:
where (p.user in ($variable_with_all_results))
I tried:
$stmt = $mysqli->prepare("select f from f1 where user = '1' and block = 0");
$stmt->execute();
$stmt->bind_result($variable_with_all_results);
But I cannot use this variable on the select, the mysql is not recognizing it. Any ideas?
You should be able to do what you want like this:
$stmt = $mysqli->prepare("select GROUP_CONCAT(f) from f1 where user = '1' and block = 0");
$stmt->execute();
$stmt->bind_result($variable_with_all_results);
$stmt->fetch();
Note you need to add a GROUP_CONCAT aggregation function around f in the query, this will give you a list like 1,5,6. Also you need to do a fetch on the statement to get the result into your variable.
Then you should be able to make a new query like this:
$sql = "SELECT ...
WHERE p.user in ($variable_with_all_results)";
bind_result wont work in that way, you should use bind_param().
But using IN (?) won`t do.
You will need to bind each id separately, some think like this:
$stmt->bind_param("select f from f1 where (p.user in (select f from fl where user = IN (?,?,?,?,?) and block=0))", $id1, $id2,$id3, $id4, $id5);
This answer https://stackoverflow.com/a/17228326/2271198 explain better who bind_param works

how to select exact json value in mysql query condition

I am trying to select exact json value in mysql query condition, currently i am using LIKE and it work but like returns false positive.
my code is::
$id='1';
json data example:: ["1","12","38"]
$sql="SELECT * FROM `posts` WHERE `json_column` LIKE '%".$id."%' ";
with this query, it returns both 1 and 12. how can i get just 1?
Note the extra quotes:
$sql="SELECT * FROM posts WHERE json_column LIKE '%\"$id\"%'";
However, this is wide open to SQL inject if $id comes from user input. Be careful.
The more secure method would be to use parameterised queries with PHPs prepared statements as follows:
$stmt = $dbh->prepare("SELECT * FROM posts WHERE json_column LIKE '%\"?\"%'");
$stmt->bindParam(1, $id);

Mysqli query Injection , how to inject the SQL query string?

Let's consider i have this line of code
$result = $mysqli->query("SELECT * from myTable where field='".$_GET['var']."');
IMHO this is vulnerable to SQL injections.
So I'd like to prove it trying by sending via Get / URL a "var" param that will inject the query, with potential malicious code.
I actually tryed this:
var = "1'; TRUNCATE myTable; ";
I tryed to print out the SQL string query before executing it and it's actually 2 SQL valid statements.
SELECT * from myTable where field='1'; TRUNCATE myTable;
1st problem
But actually itseems that mysqli->query will not execute 2 statements at once. Isn't it?
2nd problem
I see that a common technique to Inject queries is to per form injection then add comment chars to get rid of the tail of the SQL.
Example:
"SELECT * from myTable where field='".$_GET['var']."' AND field2 IS NOT NULL"
Can be injected with :
var = "1'; TRUNCATE myTable; # ";
But this problem arise and I'm missing the trick to get rid of it
if the SQL string in the code have new lines e.g. :
"SELECT * from myTable where field='".$_GET['var']."'
AND field2 IS NOT NULL"
If i use the above "var" the final result is
SELECT * from myTable where field='1'; TRUNCATE myTable; #
AND field2 IS NOT NULL
Second line won't be commented
How to test injection on this?
Many thanks.
1st problem But actually it seems that mysqli->query will not execute 2
statements at once. Isn't it?
That's right, if you want to execute multiple statements you need to use mysqli->multi_query. You can find a good explanation about multiple statements here: http://www.php.net/manual/en/mysqli.quickstart.multiple-statement.php
But this problem arise and I'm missing the trick to get rid of it
The problem arises because you are using multiple statements, and mysqli->query does not support them.
About your queries:
$result = $mysqli->query("SELECT * from myTable where field='".$_GET['var']."');
You can inject this using for example 1' OR 1=1; that would return all entries of myTable on the query result.
"SELECT * from myTable where field='".$_GET['var']."' AND field2 IS NOT NULL"
Here you could use 1' OR 1=1 UNION ALL SELECT * FROM myTable WHERE '1'='1
Nowadays there are tools that can automatically check SQL injection for you, take a look at SQL Inject Me (Firefox Addon) for example.

Categories