Вставка с использованием подготовленных операторов через MySqli не может правильно вставить все данные

Я использую MySqli для вставки фрагмента содержимого страницы в базу данных в таблице content со следующими столбцами: id, name, content, parent, order, где содержимое имеет тип TEXT. Однако проблема заключается в том, что при выполнении оператора вставки он вставляет новую запись в таблицу, но не вставляет значения content и parent, в то время как правильно вставляет значения name и order. Я проверил возвращаемые значения всех функций подготовки, и все они вернули true или не выдали ошибок, поэтому я очень запутался в том, что происходит.

Свойства класса ($this->Content и $this->Parent) заполнены и содержат правильные данные. Кроме того, часть функции update/edit работает просто отлично (поскольку подготовленная функциональность обеих этих частей совершенно одинакова, это странная ошибка).

Это код, который выполняет запросы. переменная $type может принимать два значения: edit или new, и когда ее new, она не работает должным образом.

public function Save($type)
{
    if($type == "edit")
    {
        $query = "UPDATE `content` SET `name` = ?, `content` = ?, `parent` = ? WHERE `id` = ?";
        $stmt = $this->sql->prepare($query);
        $stmt->bind_param("ssii", $this->Name, $this->Content, $this->Parent, $this->ID);
    }
    else if ($type == "new")
    {
        $query = "INSERT INTO `content`(`name`, `parent`, `content`, `order`) VALUES(?, ?, ?, 999)";
        $stmt = $this->sql->prepare($query);
        $stmt->bind_param("ssi", $this->Name, $this->Content, $this->Parent);
    }       
    if(!$stmt->Execute())
        echo "Failed saving content-object with ID $this->ID" . mysqli_error($this->sql);
    $stmt->close();
}

Я понятия не имею, почему часть edit работает отлично, а часть new — нет. Запрос действительно вставляет новую строку с правильным именем и значениями порядка, поэтому я предполагаю, что это как-то связано с функцией bind_param. Строка в базе данных всегда имеет значение 0 как для content, так и для parent.


person Joey Dewd    schedule 12.04.2014    source источник
comment
Прежде всего: stackoverflow.com/a/22662582/285587   -  person Your Common Sense    schedule 12.04.2014
comment
@YourCommonSense: добавлен перед созданием объекта MysqlI. Никаких ошибок не показал, хотя после вставки.   -  person Joey Dewd    schedule 12.04.2014
comment
@JoeyDewd Ваша привязка и порядок значений неверны для вставки нового контента. Смотрите мой ответ ниже   -  person Hüseyin BABAL    schedule 12.04.2014
comment
вам не нужно тогда if вокруг `$stmt-›Execute()` тогда   -  person Your Common Sense    schedule 12.04.2014
comment
@YourCommonSense: Ах, хорошо, это приятно знать. Благодарность   -  person Joey Dewd    schedule 12.04.2014


Ответы (2)


Вы связали неправильно;

Ваши типы значений должны быть sis, а также неправильный порядок значений. См. обновление ниже;

...
else if ($type == "new")
{
    $query = "INSERT INTO `content`(`name`, `parent`, `content`, `order`) VALUES(?, ?, ?, 999)";
    $stmt = $this->sql->prepare($query);
    $stmt->bind_param("sis", $this->Name, $this->Parent, $this->Content);
}
....
person Hüseyin BABAL    schedule 12.04.2014
comment
Вы правы, похоже я перепутала свой заказ и глупо, что не увидела этого. Я смотрел на этот кусок кода в течение нескольких часов. Я отредактировал код, и теперь он работает идеально. Спасибо - person Joey Dewd; 12.04.2014
comment
Да, пробовал, но я могу принять это только через определенное время после создания вопроса;) - person Joey Dewd; 12.04.2014

я не уверен, в чем проблема, мне не нравится эта логика if/else. Я предпочитаю использовать переключатель сам.

public function Save($type)
{
    switch($type) {

        case 'edit': 

        $query = "UPDATE `content` SET `name` = ?, `content` = ?, `parent` = ? WHERE `id` = ?";
        $stmt = $this->sql->prepare($query);
        $stmt->bind_param("ssii", $this->Name, $this->Content, $this->Parent, $this->ID);

        if(!$stmt->Execute()) {
            echo "Failed saving content-object with ID $this->ID" . mysqli_error($this->sql);
                    $stmt->close();
        }else{
                    $stmt->close();
            }
        break;

        case 'new':

        $query = "INSERT INTO `content`(`name`, `parent`, `content`, `order`) VALUES(?, ?, ?, 999)";
        $stmt = $this->sql->prepare($query);
        $stmt->bind_param("ssi", $this->Name, $this->Content, $this->Parent);

        if(!$stmt->Execute()) {
            echo "Failed saving content-object with ID $this->ID" . mysqli_error($this->sql);
                    $stmt->close();
        }else{
                     $stmt->close();
            }
        break;

        default: die;

    }
}

Еще одна вещь, которую я заметил: вы подключаетесь к своей базе данных и выполняете свои запросы крайне неортодоксальным образом. просто создайте соединение с базой данных в файле конфигурации, который вам нужен на всех страницах, и примените его глобально, а затем получите к нему доступ через глобальный массив внутри вашей функции, например global $database. тогда вам будет легче выполнять свои действия, например $stmt = $database->prepare("INSERT INTO ....");

другое дело, не используйте двойные кавычки в php, если только вы не собираетесь оставлять в них переменную, например echo "welcome to my website, $username";

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

person r3wt    schedule 12.04.2014
comment
@ r3wt: Спасибо за советы (хороший совет с двойными кавычками), да, база данных на самом деле является глобальным объектом, который передается объекту класса, но этот второй шаг на самом деле не нужен, так что вы правы. Кроме того, логика правильная, в ней нет ничего плохого. - person Joey Dewd; 12.04.2014
comment
Это фантастическая коллекция суеверий. @JoeyDewd НИ ОДИН из этих советов не соответствует действительности. - person Your Common Sense; 12.04.2014
comment
@YourCommonSense: о, извините: p, я не эксперт в PHP, поэтому советы быстро кажутся мне законными. Спасибо, что указали на это - person Joey Dewd; 12.04.2014
comment
@YourCommonSense На самом деле все, что я сказал, было правдой. - person r3wt; 12.04.2014