Страницы

Поиск по вопросам

воскресенье, 24 ноября 2019 г.

mysql_fetch_array() expects parameter 1 to be resource (or mysqli_result), boolean given


Я пытаюсь получить данные из таблицы MySQL, но вылезает одна из этих ошибок:


  mysql_fetch_array() expects parameter 1 to be resource, boolean given


или


  mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given


Вот мой код:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE $username");

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}


Оригинальный вопрос.
    


Ответы

Ответ 1



Как избежать такой ошибки Эта ошибка - вторичная. И в правильно спроектированном приложении возникать в принципе не должна. Она лишь сигнализирует о том, что предыдущая функция, которая выполняла SQL запрос, окончилась неудачей, но при этом о причине неудачи никакой информации не несёт. Чтобы таких ошибок в коде не возникало, необходимо проверять результат той само предыдущей функции, выполнявшей SQL запрос. Но делать это надо с умом, а не так, ка советуют неспециалисты, десятилетиями переписывая друг у друга один и тот же код, не понимая его смысла и не сталкиваясь с результатами его работы (весьма плачевными) на практике. Вызывая функцию mysql_query(), необходимо всегда проверять результат её работы. если функция вернула не корректный ресурс, а пустоту, то необходимо, во-первых, получит от mysql сообщение об ошибке, а во-вторых, транслировать его в ошибку РНР (это принципиальный момент, которого начинающие пользователи РНР не понимают поголовно). А в-третьих, очень полезно бывает добавить в сообщение об ошибке сам запрос. За первое отвечает функция mysql_error(), за второе - trigger_error(), а для третьег необходимо всегда сначала присваивать запрос переменной. Таким образом, любой вызов mysql_query() должен выглядеть так: $sql = "SELECT ..."; $res = mysql_query($sql) or trigger_error(mysql_error()." in ". $sql); Таким образом, при возникновении ошибки исполнения запроса, пользователь РНР буде немедленно проинформирован точно так же, как о любых других возникающих в работе скрипта ошибках. А до ошибки "expects parameter" дело уже не дойдет. В принципе, ещё лучше чем trigger_error(), было бы бросить исключение. Но поскольку throw new Exception() не подставишь так красивенько через or в ту же строку; начинающие пользователи РНР очень плохо представляют себе механизм исключений и тут же начинают использовать его неправильно; расширение mysql уже потеряло всякий смысл, а два оставшихся - mysqli и PDO умеют транслировать ошибки БД в исключения автоматически, то предлагать исключения для mysql_query() как-то глупо. Но в любом случае, как бы ни обрабатывалась ошибка, она должна следовать двум непреложным правилам: Никаких echo и die()!!! Ошибки базы данных должны всегда транслироваться в ошибк РНР и выводиться туда, куда выводятся все остальные. Если на сайте запрещен вывод ошибок в браузер, то ошибки БД не должны быть исключением из этого правила. Сообщение об ошибке обязательно должно содержать имя файла и строку, в которой произошла ошибка, а по возможности - ещё и трассировку вызовов. Как исправить ошибку. Надо прочитать сообщение об ошибке. Это звучит банальностью, но на удивление никто из неспециалистов раздающих совет никогда этого не упоминает! При том что прочтение текста ошибки помогает в сто раз лучше шаманских телодвижений типа "пересчитайте все кавычки": Во-первых, mysql сразу скажет, в чем суть ошибки. Если в базе нет таблицы, к которой мы обращаемся, или сервер весь целиком упал, то пересчитывать кавычки бесполезно. Во-вторых, если ошибка все-таки в синтаксисе, то mysql точно укажет место где е искать - она процитирует кусок запроса, начинающийся сразу за ошибкой. Как раз и навсегда избавиться от ошибок синтаксиса, вызванных данными. Если проблема всё-таки в синтаксисе, и при этом вызвана переданными в запрос данными то Самой Дурацкой Идеей будет "экранировать ваши значения с помощью mysql_real_escape_string()". И уж тем более глупостью будет применять эту функцию для защиты от SQL инъекций. Она не для этого предназначена. Для того, чтобы навсегда избавиться от любых проблем, связанных с передаваемыми запрос переменными, необходимо перестать вставлять их в строку запроса напрямую. А делать это только через посредника, называемого "плейсхолдер". Драйвер для работы с БД через плейсхолдеры можно написать на основе любого API будь это mysql, mysqli или PDO. Но поскольку, во-первых, для этого нужно обладать специальным знаниями, а во-вторых начинающие пользователи РНР до ужаса боятся любых готовых библиотек, предпочитая пользоваться лишь встроенными средствами языка, то у них остаётся только один выбор - PDO. Mysqli Чтобы транслировать ошибки базы данных в ошибки РНР, в mysqli не нужно проверят результат каждой функции. Вместо этого достаточно перед коннектом написать вот такую строчку: mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); и тогда все ошибки БД будут порождать исключения, которые по умолчанию становятся фатальными ошибками РНР и в таком виде станут доступными программисту.

Ответ 2



Откуда берётся ошибка Эта ошибка возникает, если запрос не может быть выполнен. Функции, которые могу к ней привести: mysql_fetch_array/mysqli_fetch_array() mysql_fetch_assoc()/mysqli_fetch_assoc() mysql_num_rows()/mysqli_num_rows() Если с запросом всё в порядке, и просто результат его выполнения пустой, то ошибка не возникает. К ошибке приводит только неверный синтаксис SQL. Как найти источник ошибки Убедитесь, что на сервере, на котором вы ведёте разработку, включено отображени всех ошибок. Вы можете включить его из PHP, выполнив error_reporting(-1); (можно разместить этот код в конфигурационном файле вашего сайта, например). Если при попытке выполнения запроса будут обнаружены ошибки в синтаксисе, то они будут отображены. Используйте mysql_error(). Эта функция вернёт строку с текстом ошибки, если таковая возникла при выполнении последнего запроса. Например: mysql_connect($host, $username, $password) or die("Ошибка подключения"); mysql_select_db($db_name) or die("Ошибка выбора БД"); $sql = "SELECT * FROM table_name"; $result = mysql_query($sql); if ($result === false) { echo mysql_error(); } Выполните ваш запрос в командной строке MySQL или из инструмента вроде phpMyAdmin. Если в запросе есть синтаксическая ошибка, то она будет отображена. Убедитесь, что в запросе верно расставлены кавычки. Это частая причина синтаксических ошибок. Убедитесь, что вы экранируете ваши значения. Если в строке присутствует кавычка это может привести к ошибке (а также сделать ваш код уязвимым к SQL-инъекциям). Используйте для этого mysql_real_escape_string(). Убедитесь, что вы не используете одновременно функции mysqli_* и mysql_*. Их использование нельзя смешивать. (Если вы не знаете, что выбрать, отдайте предпочтение mysqli_*.) Советы Не используйте функции mysql_* в новом коде. Разработчики PHP больше не поддерживаю и не развивают их, они отмечены как устаревшие, и в будущих версиях будут удалены. Ознакомьтес с понятием prepared statement и переходите на использование PDO (PHP Data Objects) или MySQLi (MySQL improved). Это избавит вас от проблем с экранированием значений и убережёт от SQL-инъекций. И MySQLi, и PDO поддерживают режим, в котором при ошибках выбрасываются исключения В новом коде следует использовать этот подход, потому что он помогает обрабатывать ошибки в одном месте, а не размазывать проверки по всему коду, и позволяет обработке ошибок не зависеть от внешних условий (от конфигурации). Сравнение возможностей PDO и MySQLi. Если вкратце, то PDO — это общий слой над базам данных, который позволяет относительно легко переключать СУБД; а MySQLi даёт доступ к некоторым дополнительным возможностям СУБД MySQL. Преимущественно перевод ответа.

Ответ 3



$username = $_POST['username']; $password = $_POST['password']; if ($result = mysql_query("SELECT * FROM Users WHERE UserName LIKE $username") and mysql_num_rows($result)){ while($row = mysql_fetch_assoc($result)) { echo $row['FirstName']; } }else{ if (!mysql_num_rows($result)){ echo "empty result"; }else{ echo mysql_error(); } }

Комментариев нет:

Отправить комментарий