Обновление Mysqli, вызывающее вызов функции-члена bind_param(), ошибка

Привет, у меня есть форма поля 70/80, которую мне нужно вставить в таблицу, поэтому вместо того, чтобы вручную создавать один огромный оператор вставки, я сначала создал таблицу в моей БД из имен входов в форме, вот код, который я использовать для создания / изменения таблицы

function createTable($array, $memberMysqli)
{
   foreach ($array as $key => $value)
   {
            //echo "<p>Key: ".$key." => Value: ".$value . "</p>";
            $query = "ALTER TABLE questionnaire ADD ".$key."  text";

            if($stmt = $memberMysqli->prepare($query))
            {
                $success = $stmt->execute();
            }
   }
         echo "<h1>Array count: ". count($array) ."</h1>" ;
}

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

$stmt = $memberMysqli->prepare("INSERT INTO questionnaire(userid) VALUES (?)");

$stmt->bind_param('s', $_POST['userid']);
$stmt->execute();
$rowid = $stmt->insert_id;
$stmt->close();

$memberMysqli->autocommit(FALSE);

function updateColumn($memberMysqli, $query, $uid, $value) 
{
    if ($value) 
    {
        $stmt = $memberMysqli->prepare($query);
        //Throws bind param error here
        $stmt->bind_param("ss", $value, $uid);
        $stmt->execute();
    }
}

function loopInputs($array, $memberMysqli, $rowid)
{
     foreach ($array as $key => $formvalue)
     {
        var_dump($key);
        updateColumn($memberMysqli, "UPDATE questionnaire SET $key = ? WHERE id = ?", $rowid, $formvalue);
     }
}

loopInputs($_POST, $memberMysqli, $rowid);

$memberMysqli->commit();
$memberMysqli->close();

Это приводит к ошибке параметра привязки, и я понятия не имею, почему. Любая помощь будет отличной.

1 ответ

Решение

О, давайте попробуем канонический ответ.

Call to a member function (или же expects parameter 1 to be mysqli_result, boolean given для процедурного стиля) не сама ошибка, а просто симптом, для какой-то другой проблемы.
Это сообщение об ошибке означает, что ни один объект не был создан там, где должен.

Итак, возникла проблема с созданием $stmt объект.
Скорее всего это проблема с запросом. Итак, нам нужно отследить эту ошибку.

Mysqli не скажет вам, что происходит, если не спросить явно. Таким образом, вы должны всегда проверять результат каждой функции mysqli, взаимодействующей с сервером, и если результат равен FALSE - проверять $mysqli->error,

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

Если вы используете mysqli_query() по всему коду приложения, не инкапсулируя его в некоторый вспомогательный класс, trigger_error() это хороший способ вызвать ошибку PHP, так как он также сообщит вам файл и номер строки, в которой произошла ошибка

Итак, все ваши prepare()выполнить () и query() звонки должны быть написаны так:

$stmt = $mysqli->prepare($query) or trigger_error($mysqli->error."[$query]");

или в процедурном стиле

$res = mysqli_query($mysqli,$query) or trigger_error(mysqli_error($mysqli)."[$query]");

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

Однако, если вы инкапсулируете свой запрос в некоторый класс, файл и строка из ошибки триггера будут совершенно бесполезны, поскольку они будут указывать на сам вызов, а не на код приложения, вызвавший определенную проблему. Таким образом, при выполнении инкапсулированных команд mysqli необходимо использовать другой способ:

$result = $mysqli->query($sql);
if (!$result) {
    throw new Exception($mysqli->error." [$query]");
}

Исключение предоставит вам трассировку стека, которая приведет вас туда, откуда был вызван ошибочный запрос.

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

error_reporting(E_ALL);
ini_set('display_errors',0);
ini_set('log_errors',1);

в то время как на локальном сервере разработки можно делать ошибки на экране:

error_reporting(E_ALL);
ini_set('display_errors',1);

и, конечно, вы никогда не должны использовать оператор подавления ошибок (@) перед вашими утверждениями.

Другие вопросы по тегам