Mysqli update throwing Вызов функции-члена bind_param()

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

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

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

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

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

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

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

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

Итак, все ваши вызовы prepare(), execute() и 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]");
}

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

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

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

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

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

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