Mysql error when counting rows
I have a problem when trying to count the rows in a table.
The variable $username_me equals to the session username. None of them is in an if or else statement.
The error i get is:
Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in /home/*/public_html/**/sidebar.php on line 21
Line 21 is the last line in the code bit i pasted.
//Count unread 开发者_开发技巧oneliners
$oneliners_sql = "SELECT * FROM oneliners WHERE to_user='$username_me' AND read=0";
$oneliners_query = mysql_query($oneliners_sql);
$oneliners_num = mysql_num_rows($oneliners_query);
- Your code is vulnerable of SQL Injection. There is also an xkcd strip on the argument :-)
If magic_quotes_gpc are not enabled (and they shouldn't, magic quotes were one of the many design mistakes of PHP and they are now deprecated), a hacker (or most likely a bot!) could freely alter your queries causing all sort of troubles to your site.
The proper way to fix this serious problem, is by using Prepared Statements, for instance with PDO. Alternatively you can use mysql_real_escape_string:
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
The trouble with mysql_real_escape_string
is that you've to remember to always use it, while with prepared statements these issues are taken care for you. Also if you're not using prepared statements you can use intval
to clean your integer inputs.
Let me stress it once more: SANITIZING YOUR INPUTS IS VERY IMPORTANT. You should not trust anything that comes from the user.
Your problem is caused by mysql_query returning FALSE when the query fails. If the query fails, mysql_query return FALSE instead of resource. You can call mysql_num_rows on resource, not on FALSE. (From the manual: mysql_query() returns a resource on success, or FALSE on error).
The error is caused by the
read
field name, since is a reserved word. Try to quote it with backticks (`) or even better, rename it.To find out whether a row exists or not you can use
COUNT(*)
orSELECT 1
With COUNT
the query will always return a value of 0 or 1 (I suppose that you've a unique index on to_user
), except when the query fails of course.
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
With SELECT 1
the query will return 1 if the row exists, otherwise it won't return any row.
$sql = "SELECT 1 FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0 LIMIT 1";
Which one to use depends if you need a count of the rows or you just need to know whether a row exists or not. If there is an unique index, they should be computationally very similar anyway.
.1. read
is mysql reserved word and must be quoted in backticks:
$sql = "SELECT * FROM oneliners WHERE to_user='$username_me' AND `read`=0";
.2. never use SELECT * to count rows. Use SELECT count(*) instead.
.3. always run all your queries this way to see any error occurred.
//Count unread oneliners
$sql = "SELECT count(*) FROM oneliners WHERE to_user='$username_me' AND `read`=0";
$result = mysql_query($sql) or trigger_error(mysql_error()." ".$sql);
$row = mysql_fetch_row($result);
$oneliners_num = $row[0];
never use die()
for this purpose, despite of all these stupid suggestions.
.4. Create a function for such a usual task.
function getOne($sql) {
$result = mysql_query($sql) or trigger_error(mysql_error()." ".$sql);
if ($row = mysql_fetch_row($result)) {
return $row[0];
}
}
So, you'll be able to get your num with one line
$oneliners_num = getOne("SELECT count(*) FROM oneliners WHERE to_user='$username_me' AND `read`=0");
mysql_query
returned false instread of mysql result. So, there are some errors on your query or connection. You may read error with mysql_error
精彩评论