Parameterized Queries PHP/MySQL [duplicate] - php

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I create a PDO parameterized query with a LIKE statement in PHP?
PHP PDO prepared statement — mysql LIKE query
I'm trying to make a search engine for my website, and right now I'm just trying to make sure the connection is all and well. Here is my code thus far:
EDITED CODE (Still doesn't work, but here's where I'm at with the suggestions thus far):
$db = new PDO("mysql:host=".DB_SERVER.";dbname=".DB_NAME, DB_USER, DB_PASS);
$stmt = $db->prepare("SELECT * FROM table_1 WHERE name LIKE ? ORDER BY bid DESC");
$stmt->bindParam(1, "%{$_GET['s']}%", PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll();
I tried to see if the different methods of execute would do anything, but regardless of which way above I write it, I get the same result, nothing. I want the % wildcard in there so it does it'll search anywhere in name. On that note, am I using it correctly? The thing that confuses me most is when I type in the exact same query into PHPMyAdmin, the query runs through fine, so my guess is that I'm screwing up the PDO somewhere.
EDIT: PHPMyAdmin Query:
SELECT *
FROM table_1
WHERE name LIKE '%Test%'
ORDER BY bid DESC
LIMIT 0 , 30
This returns 1 result, as it is expected to. What is different about my code and this query? :/

I don't really understand what your question is, but I'm guessing you don't know how to add the %? If so, try this:
$stmt = $db->prepare("SELECT * FROM table_1 WHERE name LIKE ? ORDER BY bid DESC");
$stmt->bindValue(1, "%{$_GET['s']}%", PDO::PARAM_STR);
$stmnt->execute();
// fetch and win! :-)
A little explanation:
PDO will quote and escape the parameter ? appropriately. This means, that if you are binding hello, PDO will substitute ? with 'hello' (note the quotes). Therefore, in order to have the % inside the quotes, you will have to add them to what is binded, in this case $_GET['s'].

Related

SELECT within SELECT PDO prepared statement [duplicate]

This question already has answers here:
Are PDO prepared statements sufficient to prevent SQL injection?
(7 answers)
Closed 7 years ago.
I'm thinking of an example like this one:
The request hits a page at an url (by whichever means), with a parameter. example.com/api/page?name=bob. It's my understanding that you should do a prepared statement to get the $_POST[name]parameter and make sure it's not anything funky, but it does so by evaluating the expression.
My first question is: How does it do so (evaluate the expression)?
My second question is:
What if a user inputs something along the lines of "SELECT * FROM users" or "DROP TABLE users" that gets passed to the $_POST['name'] parameter (the ?name=bob at the end), what would happen in that case?
Just as an example, the final query would be something like
SELECT name, continent FROM world
WHERE continent IN
(SELECT continent FROM world WHERE name='Brazil')
the second select acting as the user input parameter - so $_POST['name'] contains this query SELECT continent FROM world WHERE name='Brazil'
Lastly, the third question i have is how can i protect against something like that?
I'm guessing PDO is design specifically to prevent query within query(?), but after reading around a bit i'm still quite confused.
I'm still learning all of this so if i'm not clear or specific enough in my inquiry please let me know, and i'll try and address that.
EDIT:
To clear any confusion, what i'm doing is this:
$pdo = new PDO('..');
$sql = 'SELECT id FROM users WHERE username = :username';
$statement = $pdo->prepare($sql);
$statement->bindParam(':username', $_POST['username']);
Question is, what if $_POST['username'] contains 'SELECT * FROM users' (or any other query) ?
How does prepare() work? Can what i described actually present a security hole? I need some help in understanding this.
To clear any confusion, what i'm doing is this:
$pdo = new PDO('..');
$sql = 'SELECT id FROM users WHERE username = :username';
$statement = $pdo->prepare($sql);
$statement->bindParam(':username', $_POST['username']);
Question is, what if $_POST['username'] contains 'SELECT * FROM users' (or any other query) ?
This query would return the ids of all users with the username "SELECT * FROM users".
By passing $_POST['username'] as parameter the database knows that whatever string $_POST['username'] may contain it is NOT part of the query. It's just a string.
This prevents SQL injection since the parameter will NOT be executed. This also means that
SELECT name, continent FROM world
WHERE continent IN
(SELECT continent FROM world WHERE name='Brazil')
the second select acting as the user input parameter - so $_POST['name'] contains this query SELECT continent FROM world WHERE name='Brazil'
won't work. Because you can't include queries in parameters. Well you can but they will not be executed.

PHP sqlsrv_query dynamic order by clause

(Note that this is for MSSQL, not MYSQL)
Does anyone know why this doesn't work?
$query = "SELECT * FROM table WHERE SeriesID = ? ORDER BY ? ?";
$result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));
I don't see any errors, but no results are returned.
When I don't have the ORDER BY portion, it works. It's the second and third question marks that kill it.
$conn->getData() is calling sqlsrv_query() function...
There is a similar question here which I answered with a workaround, but I'd like to find out why this doesn't work as I think it should.

Inserting values into a table under conditions

Im trying to insert two values into a table if one condition is met and another is not met.
I've found a tutorial on the matter but i can't seem to get it to work.
The tutorial explains how to create a simple PHP like button, and has two tables, articles and articles_likes.
articles has two columns: id and title.
articles_likes has three columns: id, user and article.
The code in the tutorial looks like this:
$db->query("
INSERT INTO articles_likes (user, article)
SELECT {$_SESSION['user_id']}, {$id}
FROM articles
WHERE EXISTS (
SELECT id
FROM articles
WHERE id = {$id})
AND NOT EXISTS (
SELECT id
FROM articles_likes
WHERE user = {$_SESSION['user_id']}
AND article = {$id})
LIMIT 1
");
Now first of all, im using PDO with $query = $pdo->prepare(" .. "); and question marks plus bindValue() to avoid SQL injections, and all that is working fine with other SQL statements, but this one does not seem to work.
I've googled the INSERT INTO .. SELECT .. FROM syntax, and W3schools explains it as copying values from one table into another one. So how is this even working in the tutorial? articles has a completely different structure, and he is inserting $variables into the SELECT statement.
Can anyone explain why this works in the first place, and how it would work in PDO?
Edit:
Here is my own code (I've added $value because my code is for a binary rating instead of a like):
global $pdo;
$query = $pdo->prepare("
INSERT INTO quote_ratings (user_ip, quote_id, value)
SELECT ?, ?, ?
FROM posts
WHERE EXISTS (
SELECT id
FROM posts
WHERE id = ?)
AND NOT EXISTS (
SELECT id
FROM quote_ratings
WHERE user_ip = ?
AND quote_id = ?)
LIMIT 1
");
$query->bindValue(1, $user_ip);
$query->bindValue(2, $quote_id);
$query->bindValue(3, $rating);
$query->bindValue(4, $quote_id);
$query->bindValue(5, $user_ip);
$query->bindValue(6, $quote_id);
$query->execute();
Some kind of nested SQL queries did not get bind properly and something is left by the PDO parser during the processing of query. Also there is no way to see if the the final query generated by PDO.
I will recommend to use Mysqli library to use in such scenarios. I usually encounter such issues during complex joins or executions of custom triggers. If you want to go ahead with object oriented code you can use MySQLi Class or also you could use simple procedural approach.
Atul Jindal
I i completely agree that PDO is good choice to avoid sql injections but, you know at such situations you are unable to debug your queries. But if you use mysqli wisely and properly check sql injections when you input, then there will not be a problem.
I've found the problem: PDO, by default, uses unbuffered queries. This for some reason makes the request impossible to parse. So the mode has to be changed for this request:
$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
and everything works fine from then on!

PDO Prepare statement not processing parameters

I've exhausted all efforts at what appears to be a trivial problem, but gotten nowhere.
There is a simple Prepare statement:
$qry = $core->db->prepare("SELECT * FROM users WHERE email = '?'");
$qry->execute(array('email#address.com'));
However, no rows are returned. Running the query with the parameters hardcoded into the query results in a successful selection of one row. I've tryed many different methods of doing the prepare, but even it this most simple form it isn't working.
The PDO object is stored in a singleton called Core. PDO is using the mysql driver.
Remove quotes from the query:
("SELECT * FROM users WHERE email = ?");
The reason to use placeholders (? symbol) is to forget about quotes. PDO will add them automatically.

Is there a way to see a prepared query as it will be executed on the database? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
PDO Prepared Statements
I'm using the mysqli extension in PHP and I'm wondering, is there possibly any way to see a prepared query as it will be executed on the server, e.g. The query is something like this
select * from table1 where id = ? and name = ?
but I want to see the query after the values are filled in, like this:
select * from table1 where id = 20 and name = "John"
Turn on mysql query logging and it will log all queries to a text file for you to review.
Duplicate of PDO Prepared Statements
Short answer: no. A prepared query will never be converted to the query you expect. It's executed directly by the database server. You can use mysql's query log or PDO's undocumented function debugDumpParams, but both are just approximations.
See it where?
If it's your code you have the query and you have the prepared parameters, log them separately or replace in the original query string.
If the binding will fail you will get an error, otherwise you should expect the same values to be "filled" in as you specified them.
Its the way most of the times I am debugging mysql quires:
$q = "select * from table1 where id = ".$id." and name = ".$name;
echo $q;
The output generates all variables assigned to the query.
Hope I understood you exactly, what you wanted.

Categories