If you don't want to get a full summary of what I'm trying to do skip to (Problem starts here)
I'm setting up my new site and came across a problem.
What I'm basically trying to do is to assign ads to specific countries. So for example if your from the UK you would be shown ads that we have in our UK inventory.
So I gathered some data from Google on how to detect a user's country based on their IP.
I've made a function which does this perfectly.
$ip_address= $_SERVER['REMOTE_ADDR'];
function ip_location($ip){
$parts = explode('.', $ip);
$numeric_ip = $parts[3] + (256 * $parts[2]) + (256 * 256 * $parts[1]) + (256 * 256 * 256 * $parts[0]);
$sql = "SELECT country FROM iptocountry WHERE lower_bound <= $numeric_ip AND upper_bound >= $numeric_ip LIMIT 1";
$result = mysql_query($sql);
$country = mysql_result($result, 0);
return $country;
}
$country = ip_location($ip_address);
echo $country; // Always echos the correct country
(Problem Starts here)
So this function works fine. After making this function I created a MYSQL query which uses the data from that function to select an ad to show a user.
Here is where the problem starts.
When I type this query:
$sql = "SELECT * FROM `nuevo__htmlad` WHERE `country` = 'united kingdom' AND `active` = 1 ORDER BY RAND() LIMIT 1";
using country = 'united kingdom' it works fine but when I put country = '$country'
Nothing works it never displays an ad.
Can anyone help me understand why this query doesn't work when I place the PHP variable inside it. This actually is the first time something this simple has troubled me so much.
Any help would be appreciated.
I avoid this by using a PDO driver for working with databases. This allows me to use parameters and makes it easy to reuse sql statements. Check out this article for more information.
All of the code in the answers provided here contains SQL Injection vulnerabilities. You MUST escape the user input.
http://en.wikipedia.org/wiki/SQL_injection
After asking a few questions in the comments, it turned out that the $country variable contained and additional empty space.
OP fixed it using substr_replace ($country , '' , -1). I would personaly choose trim():
$sql = "SELECT * FROM `nuevo__htmlad` WHERE `country` = '".trim($country)."' AND `active` = 1 ORDER BY RAND() LIMIT 1";
$sql= "SELECT * FROM nuevo__htmlad WHERE country='$country' AND active=1 ORDER BY RAND() LIMIT 1";
or this try this one also
$sql= "SELECT * FROM nuevo__htmlad WHERE country='$country' AND active=1 LIMIT 1 ORDER BY RAND()";
try this one:
I always use this style since country is a string
$sql= "SELECT * FROM nuevo__htmlad WHERE country='".$country."' AND active=1 ORDER BY RAND() LIMIT 1";
Related
I was wondering if it were possible to list all of the ODD ID' using PHP and SQL.
I am currently using, which shows all results:
$result = $con->query("SELECT * FROM Users");
How would it be possible to list only ODD results using PHP and SQL?
thanks in advance..
Or you can do probably faster solution:
$result = $con->query("SELECT * FROM Users WHERE id % 2");
DEMO
You can do,
SELECT * FROM Users WHERE MOD(id,2) = 1
SELECT *
FROM YOUR_TABLE
WHERE (ID_COLUMN % 2) = 1
Maybe ive been sat infront of the computer for too long but I cant seem to solve the following issue.
I am trying to select from a database based on a users id. I have hard coded it in and it works e.g.
$q = 'SELECT * FROM users WHERE id = 1 LIMIT 1';
but when I use $_GET['id'] i get an error
$q = 'SELECT * FROM users WHERE id = $_GET[id] LIMIT 1';
//mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given...
when I get this error the address bar shows
update.php?id=1
and when I simply echo $_GET['id'] that works. So why doesn't $_GET['id'] work in my query? Ive also tried setting it as a variable prior to inputting it straight into the query but that has also failed.
I would try $q = 'SELECT * FROM users WHERE id = '.$_GET[id].' LIMIT 1';
try
$q = 'SELECT * FROM users WHERE id = '.$_GET[id].' LIMIT 1';
I can't figure out why sorting will work as long as I'm not using $sort as a passed in parameter. Example below will work for sorting:
$sort = "quantity desc";
$sql = " with items as (
SELECT i.[item_id]
,i.[name]
,i.[value]
,i.[quantity]
,i.[available]
,isnull(r.awarded, 0) as awarded
, ROW_NUMBER() OVER(
ORDER BY $sort
) rowNumber
FROM [Intranet].[dbo].[Goodwell_Item] i
LEFT JOIN (
SELECT r.item_id
, COUNT(1) awarded
from [Intranet].[dbo].[Goodwell_Reward] r
group by r.item_id
) as r
ON i.item_id = r.item_id
)
SELECT *
FROM items
WHERE rowNumber BETWEEN (?) and (?)
and ( (?) = '' OR (available = (?)))
";
$params = array( $pagify['startFrom'], $end, $available, $available );
$stmt = sqlsrv_query( $conn, $sql, $params );
However if I change the line with ORDER BY to:
ORDER BY (?)
and add it to my $params like so:
$params = array($sort, $pagify['startFrom'], $end, $available, $available );
then the sort for some reason is being ignored.
Please tell me how to get the sort working in a way that doesn't allow SQL injection.
I am dealing with this exact issue right now, and cannot find anything online to help.
I have tried:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ";
$result = $conn->getData($query, array($seriesID,$sortBy));
and
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ?";
$result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));
In both cases, I get no error, and no results.
I think the only way to solve this safely is to use a switch statement before the query to manually validate the acceptable values. However, unless you're only ever dealing with one table, you can't know what the possible values are for the SortBy column.
However, if you just go with the assumption that the values at this point have already been cleaned, you can go with the non-parameterized version like this:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY " . $sortBy . " " . $sortOrder;
$result = $conn->getData($query, array($seriesID));
What I plan to do is make sure to validate sortBy and sortOrder before I pass them to the method that contains this code. By doing it this way, each place I call the code becomes responsible for validating the data before sending it. The calling code would know the valid possible values for the table (or view in this case) that it is calling. (I'm the author of both pieces of code in this case, so I know it's safe.)
So, in short, just make sure that the values at this point in the code are already cleaned and safe, and push that responsibility up one level the code that calls this code.
Alright, so basically the most simple query ever... I've done this a million times...
SELECT *
FROM purchased_items
WHERE uid = '$uid'
if $uid == 123 It works fine and returns all data in rows where uid is 123
if $uid == 351565051447743 It returns empty...
I'm positive 351565051447743 is a possible uid in some rows, i literally copied and pasted it into the table.
$uid is a string, and is being passed as a string.
This is something i've done a million times, and i've never had this simple query not work.
Any ideas why this is not working?
You're probably getting an E{some_power} representation as a string from the double.
What I mean is
$query1 = "SELECT * FROM purchased_items WHERE uid = '$uid'";
Produces:
SELECT * FROM purchased_items WHERE uid = '3.5156505144774E+14'
One way to fix it is:
$query = sprintf("SELECT * FROM purchased_items WHERE uid = '%d'", $uid);
Not sure if sql supports E format so this may or may not be the issue.
http://viper-7.com/v6MhVe
dit: Quick workaround
$format = (is_numeric($uid)) ? '%d' : '%s';
$query2 = sprintf("SELECT * FROM purchased_items WHERE uid = '{$format}'", $uid);;
What is the datatype of uid on your table? How about casting uid to another datatype?
SELECT *
FROM purchased_items
WHERE CAST(uid AS VARCHAR(25)) = '$uid'
Alright, so if you use AMFPHP apparently when you use the browser for testing it doesn't matter if you 'cast' the value as a string in the query. You need to pass it with quotes in the string in the browser interface.
I have a table with 4 record.
Records: 1) arup Sarma
2) Mitali Sarma
3) Nisha
4) haren Sarma
And I used the below SQL statement to get records from a search box.
$sql = "SELECT id,name FROM ".user_table." WHERE name LIKE '%$q' LIMIT 5";
But this retrieve all records from the table. Even if I type a non-existence word (eg.: hgasd or anything), it shows all the 4 record above. Where is the problem ? plz any advice..
This is my full code:
$q = ucwords(addslashes($_POST['q']));
$sql = "SELECT id,name FROM ".user_table." WHERE name LIKE '%".$q."' LIMIT 5";
$rsd = mysql_query($sql);
Your query is fine. Your problem is that $q does not have any value or you are appending the value incorrectly to your query, so you are effectively doing:
"SELECT id,name FROM ".user_table." WHERE name LIKE '%' LIMIT 5";
Use the following code to
A - Prevent SQL-injection
B - Prevent like with an empty $q
//$q = ucwords(addslashes($_POST['q']));
//Addslashes does not work to prevent SQL-injection!
$q = mysql_real_escape_string($_POST['q']);
if (isset($q)) {
$sql = "SELECT id,name FROM user_table WHERE name LIKE '%$q'
ORDER BY id DESC
LIMIT 5 OFFSET 0";
$result = mysql_query($sql);
while ($row = mysql_fetch_row($result)) {
echo "id: ".htmlentities($row['id']);
echo "name: ".htmlentities($row['name']);
}
} else { //$q is empty, handle the error }
A few comments on the code.
If you are not using PDO, but mysql instead, only mysql_real_escape_string will protect you from SQL-injection, nothing else will.
Always surround any $vars you inject into the code with single ' quotes. If you don't the escaping will not work and syntax error will hit you.
You can test an var with isset to see if it's filled.
Why are you concatenating the tablename? Just put the name of the table in the string as usual.
If you only select a few rows, you really need an order by clause so the outcome will not be random, here I've order the newest id, assuming id is an auto_increment field, newer id's will represent newer users.
If you echo data from the database, you need to escape that using htmlentities to prevent XSS security holes.
In mysql, like operator use '$' regex to represent end of any string.. and '%' is for beginning.. so any string will fall under this regex, that's why it returms all records.
Please refer to http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html once. Hope, this will help you.