#php #mysql-num-rows
#php #mysql-num-rows
Вопрос:
У меня проблема при попытке подсчитать строки в таблице.
Переменная $username_me равна имени пользователя сеанса. Ни один из них не находится в операторе if или else .
Ошибка, которую я получаю,:
Предупреждение: mysql_num_rows() ожидает, что параметр 1 будет ресурсным, логическим значением, заданным в /home/*/public_html/**/sidebar.php в строке 21
Строка 21 — последняя строка в коде, который я вставил.
//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);
Комментарии:
1. Измените вторую строку на
$oneliners_query = mysql_query($oneliners_sql) or die( mysql_error() );
2. У вас ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом с ‘read = 0’ в строке 1, но я тоже пытался выполнить read = ‘0’, и больше не работает
3. Далее делаем
echo $oneliners_sql;
. Проблема, вероятно, в$username_me
.4. @kaizo: вероятно
$username_me
, содержит цитату, которая разбалансирует / нарушает запрос. Сбросьте копию$oneliners_sql
here .5. попробуйте использовать обратные метки
`read`
= 0
Ответ №1:
- Ваш код уязвим для SQL-инъекций. В аргументе также есть полоса xkcd 🙂
Если magic_quotes_gpc не включен (а они не должны, волшебные кавычки были одной из многих ошибок дизайна PHP, и теперь они устарели), хакер (или, скорее всего, бот!) Может свободно изменять ваши запросы, вызывая всевозможные проблемы на вашем сайте.
Правильный способ исправить эту серьезную проблему — использовать подготовленные инструкции, например, с помощью PDO. В качестве альтернативы вы можете использовать mysql_real_escape_string:
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
Проблема в mysql_real_escape_string
том, что вы должны помнить, чтобы всегда использовать его, в то время как с подготовленными инструкциями эти проблемы решаются за вас. Также, если вы не используете подготовленные операторы, которые вы можете использовать intval
для очистки ваших целочисленных входных данных.
Позвольте мне подчеркнуть это еще раз: ОЧИСТКА ВАШИХ ВХОДНЫХ ДАННЫХ ОЧЕНЬ ВАЖНА. Вы не должны доверять ничему, что исходит от пользователя.
-
Ваша проблема вызвана тем, что mysql_query возвращает FALSE при сбое запроса. Если запрос завершается неудачно, mysql_query возвращает FALSE вместо resource . Вы можете вызвать mysql_num_rows для resource, а не для FALSE . (Из руководства: mysql_query() возвращает ресурс при успешном выполнении или FALSE при ошибке).
-
Ошибка вызвана именем
read
поля, поскольку это зарезервированное слово. Попробуйте заключить его в кавычки с помощью обратных меток (`) или, что еще лучше, переименуйте его. -
Чтобы узнать, существует строка или нет, вы можете использовать
COUNT(*)
илиSELECT 1
При COUNT
запросе всегда будет возвращено значение 0 или 1 (я полагаю, что у вас включен уникальный индекс to_user
), за исключением случаев, когда запрос, конечно, завершается неудачно.
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
При SELECT 1
запросе будет возвращено 1, если строка существует, в противном случае она не вернет ни одной строки.
$sql = "SELECT 1 FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0 LIMIT 1";
Какой из них использовать, зависит от того, нужно ли вам количество строк или вам просто нужно знать, существует строка или нет. Если есть уникальный индекс, они должны быть вычислительно очень похожи в любом случае.
Комментарии:
1. да, сначала прочитайте вопрос, а затем посмотрите мой ответ! проблема была с `
2. @waqaralamgir, ну, я уже упоминал об этом: «Ошибка вызвана именем поля чтения, поскольку это зарезервированное слово. Попробуйте заключить его в кавычки с помощью обратных меток (`) или, что еще лучше, переименуйте его.». В любом случае, рекомендуется избегать повторного использования слов.
Ответ №2:
.1. read
является зарезервированным словом mysql и должно быть заключено в обратные кавычки:
$sql = "SELECT * FROM oneliners WHERE to_user='$username_me' AND `read`=0";
.2. никогда не используйте SELECT * для подсчета строк. Вместо этого используйте SELECT count(*).
.3. всегда выполняйте все свои запросы таким образом, чтобы увидеть любую возникшую ошибку.
//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];
никогда не используйте die()
для этой цели, несмотря на все эти глупые предложения.
.4. Создайте функцию для такой обычной задачи.
function getOne($sql) {
$result = mysql_query($sql) or trigger_error(mysql_error()." ".$sql);
if ($row = mysql_fetch_row($result)) {
return $row[0];
}
}
Таким образом, вы сможете получить свое число с помощью одной строки
$oneliners_num = getOne("SELECT count(*) FROM oneliners WHERE to_user='$username_me' AND `read`=0");
Комментарии:
1. Привет, @Coll.Shrapnel, только что отредактировал пару небольших опечаток, надеюсь, вы не возражаете 🙂
Ответ №3:
mysql_query
возвращенный false instread результата mysql. Итак, в вашем запросе или соединении есть некоторые ошибки. Вы можете прочитать ошибку с mysql_error