简体   繁体   中英

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);

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(*) or SELECT 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM