Using PHP variable inside a query - php

I am using a query inside PHP as:
$query = 'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,1';
Where I am trying to insert a PHP variable instead of 1 in the limit..
$query = 'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,"'.$_GET['limit'].'"';
but it shows me an error. There are some errors in keeping $_GET['limit'].

Three things:
The way you're writing out those queries is a bit hard to read. Personally I prefer using a multi-line heredoc syntax (as per below), but this isn't strictly required;
Any user input should go through mysql_real_escape_string() to avoid SQL injection attacks. Note: "user input" includes anything that comes from the client including cookies, form fields (normal or hidden), query strings, etc.; and
You don't need to quote the second argument to LIMIT clause, which is probably the source of your problem, meaning put LIMIT 0,5 not LIMIT 0,"5".
So try:
$title = mysql_real_escape_string($_GET['title']);
$author = mysql_real_escape_string($_GET['author']);
$limit = (int)$_GET['limit'];
$query = <<<END
SELECT *
FROM #__chronoforms_UploadAuthor
WHERE text_6 LIKE "$title%"
AND text_7 LIKE "%$author%"
LIMIT 0,$limit
END;
Also, one commentor noted that % and _ should be escaped. That may or may not be true. Many applications allow the user to enter wildcards. If that's the case then you shouldn't escape them. If you must escape them then process them:
$title = like_escape($limit);
function like_escape($str) {
return preg_replace('!(?|\\)((?:\\)*)([%_])!', '$1\$2', $str);
}
That somewhat complicated regular expression is trying to stop someone putting in '\%' and getting '\%', which then escape the backslash but not the '%'.

The hash sign (#) starts a comment in SQL, which looks like your problem

Want bunch of awful answers!
a. To solve the limit problem:
$limit = intval($_GET['limit']);
and then
...LIMIT 0, $limit
in the query.
b. To sanitize $_GET['title'], as many mentioned:
$title = mysql_real_escape_string($_GET['title']);
So the final code must be
$limit=intval($_GET['limit']);
$title = mysql_real_escape_string($_GET['title']);
$author = mysql_real_escape_string($_GET['author']);
$query = "SELECT * from #__chronoforms_UploadAuthor
WHERE text_6 like '$title' and text_7 like '%$author%'
LIMIT 0, $limit";

You've enclosed the $_GET['limit'] in double-quotes, which is the source of the problem.
Try this:
$query = 'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,'.$_GET['limit'];
Also as Cletus mentions in this answer, there are many, more serious problems you need to resolve.

Remove the double-quotes around $_GET['limit']. The two numbers that the LIMIT clause takes should not be quoted.

This should work:
$query = 'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.$_GET['title'].'%" and text_7 like "%'.$_GET['author'].'%" limit 0,'.$_GET['limit'];
But you really should filter incoming data...
$query = 'SELECT * from #__chronoforms_UploadAuthor where text_6 like "%'.mysql_real_escape_string($_GET['title']).'%" and text_7 like "%'.mysql_real_escape_string($_GET['author']).'%" limit 0,"'.intval($_GET['limit']).'"';

Related

PHP mysql query using wildcards

I am in search of a way to use wildcards with the following mysql query.
public function getSetsOnMonth($setsId, $setsDate, $offset, $count)
{
$sql = sprintf("SELECT * FROM " . $this->_prefix . "media_set AS f
INNER JOIN " . $this->_prefix . "media_set_sets_assoc AS fs
ON fs.set_id = f.set_id AND fs.sets_id = '%s'
WHERE f.posted LIKE '%s'
AND f.is_active = 1
ORDER BY f.set_id DESC
LIMIT %s, %s",
mysql_real_escape_string($setsId),
mysql_real_escape_string($setsDate),
mysql_real_escape_string($offset),
mysql_real_escape_string($count));
echo $sql; exit;
$rs = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_object($rs)) {
$rows[] = $row;
}
mysql_free_result($rs);
return new XXX_Model_RecordSet($rows, $this);
}
What i am looking to do is by month so that would be (where f.posted LIKE '%s') is located
I have tried using the % in various ways and it always errors.
For instance (where f.posted LIKE '%s %') returns this error (Warning: sprintf(): Too few arguments in..).
I have also tried to use (where f.posted LIKE '$setsDate%') this does not return a sql error, however it makes my query limit the same as the date and the single quote is removed after the % sign in the sql printout.
oddly if i reverse and put the percent sign in front of $setsDate (%setsDate) is cancels out everything after the % and shows everything.
any help would be appreciated.
UPDATED 9:35 EST 03/10
Here is the sql output ('%s %%'):
SELECT * FROM media_set AS f INNER JOIN media_set_sets_assoc AS fs ON fs.set_id = f.set_id AND fs.sets_id = '1' WHERE f.posted LIKE '201312 %' AND f.is_active = 1 ORDER BY f.set_id DESC LIMIT 0, 18
Here is SQL output ('%s%%'):
WHERE f.posted LIKE '201312%'
Notice no space between.
I believe you should be escaping the percentage sign for use in a LIKE statement, as such:
WHERE f.posted LIKE '%s %%'
Your problem is that sprintf treats % as a special character, so it gets confused when you want an actual % character. The solution for that is to use %% when you want the actual % character.
However, please do not insert values into your SQL with sprintf. That is an extremely bad practice and it is responsible for most of the security vulnerabilities in PHP code. Escaping your strings is not good enough. Use parameterized queries instead.
You should use the PDO or mysqli extensions, which support parameterized queries.
There are many articles explaining why you should not splice values into your SQL. Here is one: http://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/
The way you should be doing it is discussed here: https://stackoverflow.com/a/60496/219155

Mysql Query error

What is wrong with this query?
$query2=mysql_query("SELECT * FROM $t_medici WHERE `oras` LIKE $orase") or die(mysql_error());
This code returns
Unknown column 'Bucuresti' in 'where clause'
$orase needs to be in quotes.
$query2=mysql_query("SELECT * FROM $t_medici WHERE oras LIKE '$orase'") or die(mysql_error());
Put $orase within single quotes.
Use % symbol if you need it.
If the oras field is a string then $orase should have single quotes around it:
$query2=mysql_query("SELECT * FROM $t_medici WHERE `oras` LIKE '$orase'") or die(mysql_error());
What happening is that the variable $orase contains the string Bucuresti when this line is reached and the SQL code is therefore ends like this:
...WHERE `oras` LIKE Bucuresti
But you should also escape it (to prevent SQL injection):
$query2=mysql_query("SELECT * FROM $t_medici WHERE `oras` LIKE '".mysql_real_escape_string($orase)."'") or die(mysql_error());
Also I'd put braces around any other variables in a double quoted string, i.e. {$t_medici} here:
$query2=mysql_query("SELECT * FROM {$t_medici} WHERE `oras` LIKE '".mysql_real_escape_string($orase)."'") or die(mysql_error());
On a side note, if you're using LIKE with a string like you are then any rows returned will have to Bucuresti (or whatever $orase holds) exactly, nothing before or after it (including spaces!). In this case there's no point in using LIKE at all; you might as well use = like so:
"SELECT * FROM {$t_medici} WHERE `oras` ='".mysql_real_escape_string($orase)."'"
But if you want to match any rows which has Bucuresti (or whatever $orase holds) in the oras field somehow (e.g. " Bucuresti", "Bucuresti ", "kdsbks kksd saBucurestie ", etc) then you should use % like so:
"SELECT * FROM {$t_medici} WHERE `oras` LIKE '%".mysql_real_escape_string($orase)."%'"
I.e. %Bucuresti% if $orase was to hold Bucuresti.
very familiar error when copying a query from the internet and editing it. the single quotes as highlighted above.

How to use PDO::quote without getting string surrounded by quotes?

I try to use PDO::quote to escape a string in a LIKE expression, so the user string must not be surrounded like in :
LIKE "%userStringToEscape%"
Is there a way to do that ?
$var = "%userStringToEscape%";
$var = $stmt->quote($var);
$sql = "SELECT * FROM table WHERE field LIKE $var";
same goes for the prepared statements
Use substr($db->quote($var), 1, -1)
Really though, don't. You'll end up with larger problems than the ones you started with.
The clean solution to do this is, of course, $db->quote('%'.$var.'%')
Just do:
$like = $pdo->quote("%{$userStringToEscape}%");
$sql = "SELECT * FROM field LIKE {$like}";
http://php.net/manual/en/pdo.quote.php

MySQL query: select all if REGEXP $var is empty?

$cities = "Amsterdam|Rotterdam|Den Haag"
$results = mysql_query("SELECT * FROM messages WHERE content REGEXP '$cities'");
The above code works great, but if $cities is empty, nothing is selected. I'd like to select all rows if $cities has no value. How can I achieve that? Thanks!
You will need to use a conditional in your php, which removes the where clause when your $cities variable is empty. Alternatively, you can use a regex that matches everything like /^/, but it's not particularly elegant.
you should check to see if the $cities is empty. If it is you can replace it with .* (match everything) or remove the from clause from the query (would increase performance)
$results = mysql_query("SELECT * FROM messages".
(empty($cities)? "":" WHERE content REGEXP '$cities'"));
Or probably
$results = mysql_query("SELECT * FROM messages WHERE '$cities' = '' OR content REGEXP '$cities'");

PHP mysql - ...AND column='anything'...?

Is there any way to check if a column is "anything"? The reason is that i have a searchfunction that get's an ID from the URL, and then it passes it through the sql algorithm and shows the result. But if that URL "function" (?) isn't filled in, it just searches for:
...AND column=''...
and that doesn't return any results at all. I've tried using a "%", but that doesn't do anything.
Any ideas?
Here's the query:
mysql_query("SELECT * FROM filer
WHERE real_name LIKE '%$searchString%'
AND public='1' AND ikon='$tab'
OR filinfo LIKE '%$searchString%'
AND public='1'
AND ikon='$tab'
ORDER BY rank DESC, kommentarer DESC");
The problem is "ikon=''"...
and ikon like '%' would check for the column containing "anything". Note that like can also be used for comparing to literal strings with no wildcards, so, if you change that portion of SQL to use like then you could pre-set the variable to '%' and be all set.
However, as someone else mentioned below, beware of SQL injection attacks. I always strongly suggest that people use mysqli and prepared queries instead of relying on mysql_real_escape_string().
You can dynamically create your query, e.g.:
$query = "SELECT * FROM table WHERE foo='bar'";
if(isset($_GET['id'])) {
$query .= " AND column='" . mysql_real_escape_string($_GET['id']) . "'";
}
Update: Updated code to be closer to the OP's question.
Try using this:
AND ('$tab' = '' OR ikon = '$tab')
If the empty string is given then the condition will always succeed.
Alternatively, from PHP you could build two different queries depending on whether $id is empty or not.
Run your query if search string is provided by wrapping it in if-else condition:
$id = (int) $_GET['id'];
if ($id)
{
// run query
}
else
{
// echo oops
}
There is noway to check if a column is "anything"
The way to include all values into query result is exclude this field from the query.
But you can always build a query dynamically.
Just a small example:
$w=array();
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w); else $where='';
$query="select * from table $where";
For your query it's very easy:
$ikon="";
if ($id) $ikon = "AND ikon='$tab'";
mysql_query("SELECT * FROM filer
WHERE (real_name LIKE '%$searchString%'
OR filinfo LIKE '%$searchString%')
AND public='1'
$ikon
ORDER BY rank DESC, kommentarer DESC");
I hope you have all your strings already escaped
I take it that you are adding the values in from variables. The variable is coming and you need to do something with it - too late to hardcode a 'OR 1 = 1' section in there. You need to understand that LIKE isn't what it sounds like (partial matching only) - it does exact matches too. There is no need for 'field = anything' as:
{field LIKE '%'} will give you everything
{field LIKE 'specific_value'} will ONLY give you that value - it is not partial matching like it sounds like it would be.
Using 'specific_value%' or '%specific_value' will start doing partial matching. Therefore LIKE should do all you need for when you have a variable incoming that may be a '%' to get everything or a specific value that you want to match exactly. This is how search filtering behaviour would usually happen I expect.

Categories