mysqli_fetch_assoc () очікує помилок параметра / виклику функції члена bind_param (). Як отримати фактичну помилку mysql та виправити її?


109

У моєму локальному середовищі / розробці запит 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

@YourCommonSense - З давньою назвою було простіше знайти це питання для повторної посилання.
Пол Шпігель

@Paul так, це теж моя глибока стурбованість. Я змінив назву заради пошуку Google та загального розпізнавання, оскільки для пересічного користувача PHP зв’язок між їх кодом та різними середовищами незрозумілий. Але відтоді мені теж важко це знайти. У кінцевому підсумку це є у закладках. Якщо ви можете запропонувати впізнаваний, але відповідний заголовок, це було б чудово
Ваше

Відповіді:


122

Іноді ваш 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. І проблемне місце знаходиться безпосередньо перед частиною запиту, вказаною в повідомленні про помилку.

Якщо ви не розумієте повідомлення про помилку, спробуйте надіслати його Google. А під час перегляду результатів дотримуйтесь відповідей, які пояснюють помилку, а не тупо дають рішення. У вашому конкретному випадку рішення може не працювати, але пояснення допоможе вам зрозуміти проблему і дасть змогу вирішити проблему самостійно.

Ви також повинні довіряти повідомлення про помилку. Якщо він говорить , що кількість маркерів не збігається з числом пов'язаних змінних , то він є так. Те саме стосується відсутніх таблиць або стовпців. З огляду на вибір, чи це ваша власна помилка чи неправильне повідомлення, завжди дотримуйтесь попереднього. Знову це звучить поблажливо, але сотні питань на цьому самому сайті доводять цю пораду вкрай корисною.

Перелік речей, які ви ніколи не повинні робити стосовно повідомлення про помилки

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

PS
Іноді помилок немає, але результатів також немає. Тоді це означає, що в базі даних немає даних, які б відповідали вашим критеріям . У цьому випадку ви повинні визнати цей факт, навіть якщо ви можете присягнути дані і критерії все в порядку. Вони не. Вам доведеться їх ще раз перевірити. У мене є стаття, яка може допомогти в цьому питанні, як налагодити взаємодію з базами даних . Хоча це написано для PDO, але принцип той самий. Просто дотримуйтесь цієї інструкції крок за кроком, або вирішіть проблему, або задайте відповідне питання щодо переповнення стека.


@AdamWinter використання @ завжди помиляється, і в цьому конкретному випадку є десятикратним. Повідомлення про помилки у вашій програмі - це те саме, що болить ваш організм. Це говорить вам, що щось не так, як, наприклад, ваша нога зламана. І вам доведеться виправити ногу, а не просто взяти знеболююче і продовжувати. ТЕ Ж САМЕ. PHP каже вам, що немає змінної, яку ви очікуєте. Отже, вам потрібно виправити форму чи будь-яку іншу інформацію, щоб зробити цю змінну доступною. Не просто написати код, щоб обійти помилку.
Твій здоровий глузд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.