This question already has answers here:
How do I set ORDER BY params using prepared PDO statement?
(7 answers)
Closed 9 years ago.
I have this code
$query_search = $this->db->prepare("SELECT* FROM table1 LEFT JOIN table2 ON (table1.id=table2.id) WHERE table1.nome LIKE ? ORDER BY ? DESC");
if($query_search->execute(array($cliente_procura."%",'table2.'.$ordem)))
{
//code
}
But I'm having some problems with the ORDER BY clause.
How can I use PDO and make sure my tables are in the order I want?
Binding the column names is not possible with prepared statements.
You need to use the age-old method of binding them in strings like this:
$query_search = $this->db->prepare(" SELECT *
FROM table1
LEFT JOIN table2
ON (table1.id=table2.id)
WHERE table1.nome
LIKE ?
ORDER BY table2." . $ordem . " DESC");
if( $query_search->execute( array($cliente_procura."%") ) )
From the Stackoverflow PDO tag wiki - https://stackoverflow.com/tags/pdo/info
PDO Prepared statements and identifiers.
PDO has no placeholder for identifiers, so a developer must manually
format them. To properly format an identifier, follow these two rules:
*Enclose identifier in backticks.
*Escape backticks inside by doubling them.
see - Can PHP PDO Statements accept the table or column name as parameter?
or - Which tokens can be parameterized in PDO prepared statements?
see also this comment/example from the php manual - http://us3.php.net/manual/en/book.pdo.php#69304
Related
This question already has answers here:
Can you omit PDO prepare if there's no placeholder/dynamic data in a query?
(3 answers)
Closed 4 years ago.
$sql = "select col1, col2, col3 from t1 order by date desc limit 500"
There is no place for binding anything, so do I need (and how) to make a prepared statement?
Another example:
$sql = "select col1 from t1 where col1 = 'val1' order by date desc"
If this code is placed before html output (while loading the page, without any user input values), do I need the prepared statement?
I suppose sql injection is not possible if there is no yet any interaction with users.
You don't need prepared statements if the query isn't expecting user supplied arguments.
Simple question - I do understand that if I want to run this type of query in Wordpress:
SELECT * FROM tableA WHERE variable1 = $var1
...then I need to use 'prepare', like so:
$my_query = $wpdb->get_results($wpdb->prepare("SELECT * FROM tableA
WHERE variable1 = %s", $var1) );
However, when I want to do this type of query instead:
join two tables on a column
and NOT use a variable
like this:
SELECT * FROM tableA, tableB WHERE tableA.some_col = tableB.some_other_col
...'should' I:
still use some form of 'prepare' statement to safeguard against SQL injection
or is it ok to do the following:
$my_query = $wpdb->get_results("SELECT * FROM tableA, tableB WHERE
tableB.some_col = tableB.some_other_col");
You dont need prepared statements there because there is no way that anyone could use this code for sql injection.
If you just select everything from two tables without giving any variable you can forget about prepared statements :)
I think you should stick with
$wpdb->prepare
even if you do not have any un-sanitized parameters to pass to the query.
There are few reasons why you should do that:
This is a best practice;
Consistency. If you will use the same approach for all your queries;
If you will need to pass a parameter to this query in future, it will be easier for you.
You find a discussion about this here Should I use wpdb prepare?
I have a table that contains
ID(P)(auto) NAME
-----------------------
1 Art
4 Bankie
6 Cara
The data sequence has 3 missing ID values: 2, 3 and 5.
This is my query:
$fname = $_POST['fname'];
mysql_query("INSERT INTO applicants ($fname) VALUES ('$fname')");
How can data be INSERTed in place of a missing ID value, in order to use all ID's.
What you're asking is not necessary for performance purposes, however to my knowledge there isn't a way to do this automatically. You would have to check for the missing ID ranges and assign them manually.
I would also recommend looking at the following post about SQL injection protection as it's a necessary step to maintaining a secure database connection. SQL Injection Prevention
Secondly, please do not use php's mysql_query() functions. These are deprecated and have been for some time now. MySQLi or PDO is recommended instead.
It's could be done using variable in sql query.
Let's say $name = $_POST['fname'];
Then you need insert query like this :
insert into yourtable(id,name)
select id-diff as new_id,'$name' from(
select id,id - (#x := #x + 1) as diff
from yourtable
join (select #x := 0) as t1
order by id asc
) as t2
where diff <> 0
limit 1
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 7 years ago.
There is only one way my PDO query returns result I want, but proper prepared statement gives out only column name.
This returns column name instead of queried row:
$queryPrice = "SELECT :zone FROM express WHERE kg >= :kg LIMIT 1";
$stmt = $conn->prepare($queryPrice);
$stmt->bindParam(':zone', $zone, PDO::PARAM_STR);
$stmt->bindParam(':kg', $_SESSION['weight'], PDO::PARAM_STR);
$stmt->execute();
$price = $stmt->fetchColumn();
This works, but is vulnerable to injection:
$queryPrice = "SELECT $zone FROM express WHERE kg >= :kg LIMIT 1";
$stmt = $conn->prepare($queryPrice);
$stmt->bindParam(':kg', $_SESSION['weight'], PDO::PARAM_STR);
$stmt->execute();
$price = $stmt->fetchColumn();
Why doesn't prepared statement for column name work?
Is there a safe way to achieve desired results?
On the second thought your question appears to be caused by bad database design.
Instead of having zones as columns in the table, you have to have them as data in the single column in another table. And it is clearly proven by the fact that you are trying to address a column name the way only data have to be addressed.
You have reorganize your table, leaving only one column for zones, name for example. And you'll be able to select your zone with a query like this
SELECT name FROM zones WHERE kg > :kg
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
The sql injection will work only when my query looks like below sample
SELECT * FROM login WHERE id = $my_id_va;
Assume if my query is
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
Than I will get following error
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'order by id desc' at line 1
So, this 1 or 1=1; SHOW TABLES will not work, correct?
My site was hacked successively many times.
I want one quick answer: When my query looks like the following one, what ways or which types of query can they use to hack my site?
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
What are the ways to execute the show table in the following query
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
I am also using escaping function to handle the query string values, like mysql_real_escape_string($my_id_va). Yes, obviously this for single related hack, but not sure.
Added some more
SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC
but show table not worked
If you are using PHP5, use parametarized query, use PDO.
Int cast
If id is a number, you can int-cast your variable as well. Integers are safe to use:
$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";
mysql_real_escape_string
If you want to pass a string, you can, and should, use mysql_real_escape_string, but this function escapes only those characters that are inside the string. You will still need to add quotes around the string, so:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = $x";
.. will result in the query: select * from Table where id = hello. This is obiously not a valid query, since hello should be in quotes.
Change the query to:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = '$x'";
.. and everything works fine. You add the quotes around, and mysql_real_escape_string takes care of special characters inside the string, if any.
Parameters
Another solution is to use parameterized queries. This can by done using MySQLi or PDO. The advantage is that you only tell your database where a variable should be inserted, and the database takes care of the escaping yourself.
It also may add a performance benefit, because these queries could be cached without their parameters, make a more efficient use of the query cache. This doesn't really work yet in current versions of MySQL, though.
You are right that 1 or 1=1; SHOW TABLES will give a syntax error but this will work:
1 or 1=1 --
The -- comments out the rest of the query.
In your case the value is an integer so instead of using mysql_real_escape_string you can use intval.
If you set $my_id_va to:
1 or 1=1; SHOW TABLES --
The -- will comment out the rest of the command, effectively terminating it.
I'm not sure what effect mysql_real_escape_string will have on the query. What you should be doing is parameterized queries.
1. First query somehow secured
$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));
2. Second query somehow secured
$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC",
mysql_real_escape_string($start_date),
mysql_real_escape_string($end_date));
Read the docs about sprintf if you don't understand it.
However, as others have said, it would be very very secure if you would use parameterized queries with a class such as PDO or MySQLi.