Leon1010

Я в Соц.сетях:

Теги:

Ссылки

Ошибка expects parameter 1 to be resource, boolean given

Эта ошибка — вторичная. И в правильно спроектированном приложении возникать в принципе не должна.

Она лишь сигнализирует о том, что предыдущая функция, которая выполняла SQL запрос, окончилась неудачей, но при этом о причине неудачи никакой информации не несёт.

Чтобы таких ошибок в коде не возникало, необходимо проверять результат той самой предыдущей функции, выполнявшей SQL запрос. Но делать это надо с умом, а не так, как советуют неспециалисты, десятилетиями переписывая друг у друга один и тот же код, не понимая его смысла и не сталкиваясь с результатами его работы на практике.

Вызывая функцию  mysql_query(), необходимо всегда проверять результат её работы. И если функция вернула не корректный ресурс, а пустоту, то необходимо, во-первых, получить от mysql сообщение об ошибке, а во-вторых, транслировать его в ошибку РНР (это принципиальный момент, которого начинающие пользователи РНР не понимают поголовно). А в-третьих, очень полезно бывает добавить в сообщение об ошибке сам запрос.

За первое отвечает функция  mysql_error(), за второе —  trigger_error(), а для третьего необходимо всегда сначала присваивать запрос переменной. Таким образом, любой вызов  mysql_query() должен выглядеть так:

Таким образом, при возникновении ошибки исполнения запроса, пользователь РНР будет немедленно проинформирован точно так же, как о любых других возникающих в работе скрипта ошибках. А до ошибки «expects parameter» дело уже не дойдет.

В принципе, ещё лучше чем trigger_error(), было бы бросить исключение. Но поскольку

  • throw new Exception() не подставишь так красивенько через  or в ту же строку;
  • начинающие пользователи РНР очень плохо представляют себе механизм исключений и тут же начинают использовать его неправильно;
  • расширение  mysql уже потеряло всякий смысл, а два оставшихся —  mysqli и  PDO умеют транслировать ошибки БД в исключения автоматически,

то предлагать исключения для  mysql_query() как-то глупо. Но в любом случае, как бы ни обрабатывалась ошибка, она должна следовать двум непреложным правилам:

  1. Никаких  echo и  die()!!! Ошибки базы данных должны всегда транслироваться в ошибки РНР и выводиться туда, куда выводятся все остальные. Если на сайте запрещен вывод ошибок в браузер, то ошибки БД не должны быть исключением из этого правила.
  2. Сообщение об ошибке обязательно должно содержать имя файла и строку, в которой произошла ошибка, а по возможности — ещё и трассировку вызовов.

Как исправить ошибку.

Надо прочитать сообщение об ошибке.

Это звучит банальностью, но на удивление никто из неспециалистов раздающих советы никогда этого не упоминает! При том что прочтение текста ошибки помогает в сто раз лучше шаманских телодвижений типа «пересчитайте все кавычки»:

Во-первых, mysql сразу скажет, в чем суть ошибки. Если в базе нет таблицы, к которой мы обращаемся, или сервер весь целиком упал, то пересчитывать кавычки бесполезно.
Во-вторых, если ошибка все-таки в синтаксисе, то mysql точно укажет место где её искать — она процитирует кусок запроса, начинающийся сразу за ошибкой.

Как раз и навсегда избавиться от ошибок синтаксиса, вызванных данными.

Если проблема всё-таки в синтаксисе, и при этом вызвана переданными в запрос данными, то Самой Дурацкой Идеей будет «экранировать ваши значения с помощью  mysql_real_escape_string()». И уж тем более глупостью будет применять эту функцию для защиты от SQL инъекций. Она не для этого предназначена.

Для того, чтобы навсегда избавиться от любых проблем, связанных с передаваемыми в запрос переменными, необходимо перестать вставлять их в строку запроса напрямую.А делать это только через посредника, называемого «плейсхолдер».

Драйвер для работы с БД через плейсхолдеры можно написать на основе любого API — будь это mysql, mysqli или PDO. Но поскольку, во-первых, для этого нужно обладать специальными знаниями, а во-вторых начинающие пользователи РНР до ужаса боятся любых готовых библиотек, предпочитая пользоваться лишь встроенными средствами языка, то у них остаётся только один выбор — PDO.

Советы

Не используйте функции  mysql_* в новом коде. Разработчики PHP больше не поддерживают и не развивают их, они отмечены как устаревшие, и в будущих версиях будут удалены. Ознакомьтесь с понятием prepared statement и переходите на использование PDO (PHP Data Objects) или MySQLi (MySQL improved). Это избавит вас от проблем с экранированием значений и убережёт от SQL-инъекций.

И MySQLi, и PDO поддерживают режим, в котором при ошибках выбрасываются исключения. В новом коде следует использовать этот подход, потому что он помогает обрабатывать ошибки в одном месте, а не размазывать проверки по всему коду, и позволяет обработке ошибок не зависеть от внешних условий (от конфигурации).

Сравнение возможностей PDO и MySQLi. Если вкратце, то PDO — это общий слой над базами данных, который позволяет относительно легко переключать СУБД; а MySQLi даёт доступ к некоторым дополнительным возможностям СУБД MySQL.

Запись опубликована в рубрике Кодинг с метками , .