mysqli_fetch_assoc () ожидает ошибок параметра / вызова функции-члена bind_param (). Как получить актуальную ошибку mysql и исправить ее?

111

В моей локальной среде / среде разработки запрос MySQLi выполняется нормально. Однако, когда я загружаю его в среду своего веб-хоста, я получаю эту ошибку:

Неустранимая ошибка: вызов функции-члена bind_param () для не-объекта в ...

Вот код:

global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);

Чтобы проверить свой запрос, я попытался выполнить его через панель управления phpMyAdmin, и результат в порядке.

сиопа
источник
Можем ли мы увидеть, где вы инициируете $mysqliпеременную?
Рикеш
Возможно, вашему пользователю MySQL не хватает прав для выполнения SELECTзапроса. Вы это проверили?
Амаль Мурали,
На ум приходит то, что mysqli недоступен или вы ввели неправильные учетные данные для подключения к MySQL.
NB,
Я знаю, что этот пост действительно старый. Просто подумал, что добавлю комментарий. У меня была точно такая же ошибка, и проблема заключалась в одной орфографической ошибке имени поля в БД. Как только я исправил это, все заработало. Немного глупо, но все равно.
Брайан,

Ответы:

123

Иногда ваш MySQLi код выдает ошибку , как mysqli_fetch_assoc() expects parameter..., Call to a member function bind_param()...или аналогичный. Или даже без ошибок, но запрос все равно не работает. Это означает, что ваш запрос не был выполнен.

Каждый раз, когда запрос терпит неудачу, MySQL выдает сообщение об ошибке, объясняющее причину . К сожалению, по умолчанию такие ошибки не передаются в PHP, и все, что у вас есть, это загадочное сообщение об ошибке, упомянутое выше. Следовательно, очень важно настроить PHP и MySQLi так, чтобы они сообщали вам об ошибках MySQL. И как только вы получите сообщение об ошибке, исправить ее будет проще простого.

Как получить сообщение об ошибке в MySQLi?

Прежде всего, всегда имейте эту строку перед подключением MySQLi во всех ваших средах:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

После этого все ошибки MySQL будут перенесены в исключения PHP. Неперехваченное исключение, в свою очередь, вызывает фатальную ошибку PHP. Таким образом, в случае ошибки MySQL вы получите обычную ошибку PHP. Это сразу же даст вам понять причину ошибки. А трассировка стека приведет вас к тому месту, где произошла ошибка.

Как настроить PHP в разных средах

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

Следовательно, вы должны установить для соответствующих параметров конфигурации следующие значения:

  • На сервере разработки

    • error_reportingдолжно быть установлено E_ALLзначение;
    • log_errors должен быть установлен в 1 (логи удобно вести и на компьютере разработчика)
    • display_errors должен быть установлен на 1
  • На производственном сервере

    • error_reportingдолжно быть установлено E_ALLзначение;
    • log_errors должен быть установлен на 1
    • display_errors должен быть установлен на 0

Как на самом деле это использовать?

Просто удалите код , который проверяет наличие ошибок вручную , все эти or die(), if ($result)и подобные. Просто напишите код взаимодействия с базой данных прямо сейчас:

$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();

опять же, без каких-либо условий вокруг . В случае возникновения ошибки она будет рассматриваться как любая другая ошибка в вашем коде. Например, на ПК для разработки он просто появится на экране, тогда как на действующем сайте он будет зарегистрирован для программиста, тогда как для удобства пользователя вы можете использовать обработчик ошибок (но это другая история, которая не по теме для MySQLi, но вы можете прочитать об этом в статье, указанной выше).

Что делать с появившимся сообщением об ошибке?

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

Получив сообщение об ошибке, вы должны прочитать и понять его. Это звучит слишком очевидно, если не снисходительно, но учащиеся часто упускают из виду тот факт, что сообщение об ошибке - это не просто сигнал тревоги, а фактически содержит подробное объяснение проблемы . И все, что вам нужно, это прочитать сообщение об ошибке и исправить проблему.

  • Скажем, если там написано, что определенной таблицы не существует, вам нужно проверить орфографию, опечатки, регистр букв. Также вы должны убедиться, что ваш PHP-скрипт подключается к правильной базе данных.
  • Или, если он говорит, что есть ошибка в синтаксисе SQL, вам необходимо проверить свой SQL. И проблемное место находится прямо перед частью запроса, указанной в сообщении об ошибке.

Если вы не понимаете сообщение об ошибке, попробуйте погуглить. И при просмотре результатов придерживайтесь ответов, которые объясняют ошибку, а не прямо дают решение. Решение может не сработать в вашем конкретном случае, но объяснение поможет вам понять проблему и поможет вам решить проблему самостоятельно.

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

Список вещей, которые вы никогда не должны делать в отношении отчетов об ошибках

  • Никогда не используйте оператор подавления ошибок ( @)! Из-за этого программист не может прочитать сообщение об ошибке и, следовательно, не может исправить ошибку.
  • Не используйте die()или echoили любую другую функцию для вывода сообщения об ошибке на экран безоговорочно. PHP может сам сообщать об ошибках и делать это правильно, в зависимости от среды, поэтому оставьте это PHP.
  • Не добавляйте условие для проверки результата запроса вручную (например if($result)). При включенных исключениях ошибок такое условие будет просто бесполезным.
  • Не используйте try..catchоператор для вывода сообщения об ошибке. Этот оператор следует использовать для обработки ошибок, например отката транзакции. Но никогда не используйте его только для сообщения об ошибках - как мы узнали выше, PHP уже может делать это правильно.

PS
Иногда ошибки нет, но и результатов нет. Тогда это означает, что в базе данных нет данных, соответствующих вашим критериям . В этом случае вы должны признать этот факт, даже если вы можете поклясться, что данные и критерии верны. Они не. Вы должны проверить их еще раз. У меня есть статья, которая может помочь в этом вопросе: Как отлаживать взаимодействия с базой данных . Хотя написано для PDO, но принцип тот же. Просто следуйте этой инструкции шаг за шагом, и либо ваша проблема будет решена, либо у вас появится ответный вопрос для Stack Overflow.

Ваш здравый смысл
источник
@AdamWinter использование @ всегда неверно, и в данном конкретном случае десятикратно. Сообщения об ошибках в вашей программе - это то же самое, что боль для вашего тела. Он говорит вам, что что-то не так, например, у вас сломана нога. И ногу нужно поправлять, а не просто принимать обезболивающее и продолжать. ТОЖЕ САМОЕ. PHP сообщает, что ожидаемой переменной нет. Итак, вам нужно исправить форму или что-то еще, чтобы сделать эту переменную доступной. Не просто писать код, чтобы обойти ошибку.
Ваш здравый смысл
По большей части я согласен, однако с «Вашим здравым смыслом» я не согласен: «Не просто писать код для обхода ошибки», как вы думаете, что делает try ... catch, он обходит ошибку, чтобы предотвратить выход кодовой базы неконтролируемым образом некоторые ошибки, которые вы не можете исправить в коде. Сервер EG DB исчез, вам просто нужно управлять ошибкой и обходить ее, чтобы получить правильный результат.
Barkermn01
@ Barkermn01, это вас беспокоит, но вы делаете из этого неверные выводы. Конечно, ваше приложение должно выдавать допустимый результат (который в случае ошибки «Mysql ушел» должен быть общей страницей с ошибкой 500). Но вы должны понимать, что такой действительный результат не является проблемой для кода вашей базы данных . Ваш код, связанный с базой данных, должен работать с базой данных. В то время как отображение страницы с ошибкой должно быть связано с другим кодом. См. Здесь: phpdelusions.net/articles/error_reporting
Ваш здравый смысл
Я понимаю, что это были такие вещи, как `` Но никогда не используйте его только для сообщения об ошибках '', это как бы исключает полностью объективные кодовые базы, например, мой MVC, если мои модели обнаруживают ошибку, им необходимо обработать ошибку, затем выбросьте ее обратно, чтобы мой контроллер где использование модели обернуто, может справиться с ошибкой и представить ошибку, в этом случае я использую это API, поэтому ошибка и вся информация трассировки отправляются вызову API, если она поступила из нашей удаленной системы (проверка происхождения ), так как сейчас много веб-материалов используют PHP-сервер REACT или Angular Front-end
Barkermn01
@ Barkermn01, пожалуйста, прочтите связанную статью еще раз. В любом случае, я не думаю, что это подходящее место для такой дискуссии. Если у вас есть вопрос относительно отчетов об ошибках в целом, лучше задавайте его как отдельный вопрос. Ура.
Ваш здравый смысл