Как получить информацию об ошибках MySQLi в разных средах? /mysqli_fetch_assoc() ожидает, что параметр 1 будет mysqli_result

В моей локальной среде/среде разработки 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, и результат в порядке.

+79
26 мар. '14 в 13:27
источник поделиться
2 ответа

Иногда ваш запрос терпит неудачу, и вы не знаете почему. Следовательно, очень важно настроить PHP и mysqli, чтобы сообщать вам о каждой ошибке.

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

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

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

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

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

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

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

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

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

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

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

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

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

опять же, без каких-либо условий вокруг. Если произойдет ошибка, она будет рассматриваться как любая другая ошибка в вашем коде. Например, на ПК для разработки он просто появится на экране. А для живого сайта вам понадобится обертка ошибок, но это совсем другая история, совершенно не связанная с mysqli и его ошибками.

Что делать с сообщением об ошибке, которое вы получаете

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

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

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

  • Используйте оператор подавления ошибок (@)
  • Используйте die() или echo или любую другую функцию, чтобы напечатать сообщение об ошибке на экране безоговорочно. PHP может повторить все это уже правильно, никакой помощи не требуется.
  • Тестирование результата запроса вручную (например, if($result)) просто не имеет смысла. Либо ваш запрос не удался, и вы уже получите исключение ошибки, либо все было в порядке и тестировать нечего.
  • Используйте try..catch для отображения сообщения об ошибке. Снова PHP может сделать это лучше, намного лучше.
+84
26 мар. '14 в 13:32
источник

Связанные вопросы


Похожие вопросы

@wulfnb Здравствуйте, в вашем коде обновления вы пропускаете имя файла условия условия для запроса на обновление.

Ответ для: запрос на обновление не обновляется в объектно-ориентированном php mysqli

→ Это твой код

    function update_password()
{
    $start = microtime(true);
    $conn = new mysqli('localhost', 'root', '123456', 'mydb');

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

    $sql = "SELECT id, password FROM user WHERE new_password IS NULL LIMIT 1000;";

    $pass_array = $conn->query($sql);

    if ($pass_array->num_rows == 0) {
        $time_elapsed_secs = microtime(true) - $start;
        echo "Found like its finished processing";
        echo $time_elapsed_secs;
        return true;
    } else {
        while ($row = $pass_array->fetch_assoc()) {
            $a1 = new MyCypher2();
            $pass = $a1->decryptData($row['password']);
            $a2 = new MyCypher();
            $pass_ennew = $a2->encrypt($pass);
            $sql2 = "UPDATE 'user' SET 'password' = '".$pass_ennew. "', 'new_password' = 1 WHERE = ".$row['id'].";";
            $conn->query($sql2);
        }
    }

    $conn->close();
}

@wulfnb, пожалуйста, смотрите обновленный код здесь:

    function update_password()
{
    $start = microtime(true);
    $conn = new mysqli('localhost', 'root', '123456', 'mydb');

    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

        $sql = "SELECT id, password FROM user WHERE new_password IS NULL LIMIT 1000;";

        $pass_array = $conn->query($sql);

        if ($pass_array->num_rows == 0) {
            $time_elapsed_secs = microtime(true) - $start;
            echo "Found like its finished processing";
            echo $time_elapsed_secs;
            return true;
        } else {
            while ($row = $pass_array->fetch_assoc()) {
                $a1 = new MyCypher2();
                $pass = $a1->decryptData($row['password']);
                $a2 = new MyCypher();
                $pass_ennew = $a2->encrypt($pass);
                $sql2 = "UPDATE 'user' SET 'password' = '".$pass_ennew. "', 'new_password' = 1 WHERE 'id' = ".$row['id'].";";
                $conn->query($sql2);
            }
        }

    $conn->close();
}
0
01 июл. '19 в 10:41
источник

Посмотрите другие вопросы по меткам или Задайте вопрос