PHP Предупреждение: mysql_num_rows () ожидает, что параметр 1 будет ресурсом, boolean given

Прежде всего, я пытаюсь использовать учебник для этого кода, поэтому он не мой. Я получаю ошибку ниже, когда я пытаюсь войти на мой сайт со сценарием ниже. Любая помощь будет принята с благодарностью. Также любая ссылка, направляющая меня туда, где я могу исправить эту проблему, также будет замечательной.

Предупреждение: mysql_num_rows () ожидает, что параметр 1 будет ресурсом, boolean указан в /home/u378761662/public_html/login/checklogin.php в строке 27

PHP:

<?php ob_start(); $host=""; // Host name $username=""; // Mysql username $password=""; // Mysql password $db_name=""; // Database name $tbl_name=""; // Table name // Connect to server and select databse. mysql_connect("$host", "$username", "$password")or die("cannot connect"); mysql_select_db("$db_name")or die("cannot select DB"); // Define $myusername and $mypassword $myusername=$_POST['myusername']; $mypassword=$_POST['mypassword']; // To protect MySQL injection (more detail about MySQL injection) $myusername = stripslashes($myusername); $mypassword = stripslashes($mypassword); $myusername = mysql_real_escape_string($myusername); $mypassword = mysql_real_escape_string($mypassword); $sql="SELECT * FROM $user WHERE username='$myusername' and password='$mypassword'"; $result=mysql_query($sql); // Mysql_num_row is counting table row $count=mysql_num_rows($result); // If result matched $myusername and $mypassword, table row must be 1 row if($count==1){ // Register $myusername, $mypassword and redirect to file "login_success.php" session_register("myusername"); session_register("mypassword"); header("location:login_success.php"); } else { echo "Wrong Username or Password"; } ob_end_flush(); ?> 

Я подозреваю, что вы имеете в виду SELECT * FROM user ... , а не SELECT * FROM $user ... (удалить $ ), что вызывает вашу ошибку. mysql_query() возвращает false если запрос не удался, что вы ожидаете, если $user не содержит имя вашей таблицы. Вот почему mysql_num_rows() жалуется на получение логического значения.

Кроме того, не используйте mysql_ *; он устарел .

И, как указывают другие, вы не должны хранить свои пароли в открытом виде. Вы должны хэш и солить их.


Отредактировано, чтобы объяснить, как работает соление и хеширование:

  • Сохраните соль для каждого пользователя. Соль представляет собой случайную строку символов, предпочтительно длинную, по меньшей мере, примерно дюжину символов. Он должен отличаться для каждого пользователя.

  • Когда вы создаете учетную запись пользователя или обновляете пароль, генерируйте хэш соленого пароля. Например, $hashed = hash('sha256', $raw_password.$salt); Еще лучше, сделайте много хэшей, например:

 $hashed = hash('sha256', $raw_password.$salt); for($i=0; $i<1000; $i++) { $hashed = hash('sha256', $hashed); } 

Это затрудняет извлечение паролей. На самом деле вам следует использовать bcrypt а не hash() , но это далеко не то, что принадлежит одному ответу здесь.

  • Сохраните $hashed , а не сырой пароль, в базе данных и сохраните значение соли – вам это понадобится.
  • Аутентифицировать пользователей с чем-то вроде SELECT * FROM users WHERE username = ? (используя MySQLi или PDO для выполнения подготовленных операторов). Не просто просто вставляйте имя пользователя в запрос и не используйте mysql_* .
  • После того, как вы сделали этот SELECT, есть две возможности: никаких результатов или совпадений для имени пользователя. Если вы не получили никаких результатов, имя пользователя является фиктивным. Если вы получаете результат, вы должны попытаться сопоставить пароли с чем-то вроде этого:
 $hashed_from_input = hash('sha256', $raw_password_from_input.$salt_from_the_database); for($i=0; $i<1000; $i++) { $hashed_from_input = hash('sha256', $hashed_from_input ); } if($hashed_from_input === $hashed_from_database) { // login succeeded } else { // login failed } 

Это очень сложно сделать правильно. Лучше всего использовать существующую библиотеку аутентификации пользователей, пока вы не почувствуете себя комфортно со всеми концепциями аутентификации и авторизации, а также со всеми потенциальными ловушками.

Вероятно, ваш запрос терпит неудачу, mysql_query возвращает boolean FALSE когда возникает ошибка с запросом.

В качестве дополнительной заметки расширение mysql_* устарело .

Ваш запрос неверен, по крайней мере, при использовании неназначенной переменной вместо действительного имени таблицы. Затем он не работает, поэтому возвращается логическое значение. Измените это:

 $sql="SELECT * FROM $user WHERE username='$myusername' and password='$mypassword'"; 

К этому:

 $sql="SELECT * FROM user WHERE username='$myusername' and password='$mypassword'"; 

Тем не менее, вы храните пароли в открытом тексте, что явно неправильно. Прочтите эту статью полностью, чтобы понять, почему:

Безопасный хэш и соль для паролей PHP

Наконец, как указывают люди, вы используете mysql, который устарел. Я бы рекомендовал перейти на более современный возраст с PDO. С учетом обеих реализаций вы можете:

 $db = new PDO("mysql:host=$host;dbname=$db_name", $username, $password); $sql="SELECT * FROM users WHERE username = ?"; $STH = $db->prepare($sql); $STH->execute(array($myusername)); $User = $STH->fetch(); if (!empty($User) && password_verify($mypassword, $User['hash'])) echo "Logged in"; else echo "User/password incorrect"; 

Наконец, я рекомендую использовать проверенный и принятый User Manager вместо того, чтобы делать свой собственный.