2013-08-19 6 views
8

Привет Я пытаюсь научиться правильно использовать подготовленные заявления, чтобы избежать SQL инъекций и т.д.PHP UPDATE подготовил заявление

Когда я выполнить сценарий, я получаю сообщение от моего сценария говоря 0 Рядов Поставлены, я ожидаю, это сказать 1 Rows Inserted и, конечно, обновить таблицу. Я не совсем уверен в своем подготовленном заявлении, поскольку я провел некоторое исследование, и я имею в виду, что он варьируется от примера к примеру.

Когда я обновляю таблицу, мне нужно объявить все поля или это нормально, просто обновить одно поле?

Любая информация была бы очень полезной.

index.php

<div id="status"></div> 

    <div id="maincontent"> 
    <?php //get data from database. 
     require("classes/class.Scripts.inc"); 
     $insert = new Scripts(); 
     $insert->read(); 
     $insert->update();?> 

     <form action="index2.php" enctype="multipart/form-data" method="post" name="update" id="update"> 
       <textarea name="content" id="content" class="detail" spellcheck="true" placeholder="Insert article here"></textarea> 
     <input type="submit" id="update" name="update" value="update" /> 
    </div> 

классы/class.Scripts.inc

public function update() { 
    if (isset($_POST['update'])) { 
        $stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?"); 
        $id = 1; 
        /* Bind our params */       
        $stmt->bind_param('is', $id, $content); 
        /* Set our params */ 
        $content = isset($_POST['content']) ? $this->mysqli->real_escape_string($_POST['content']) : ''; 

       /* Execute the prepared Statement */ 
         $stmt->execute(); 
            printf("%d Row inserted.\n", $stmt->affected_rows); 

           }     
          } 
+0

Вы попробовали посмотреть, что произойдет? –

+2

real_escape_string() не требуется для подготовленных операторов – Danijel

+2

В вашем SQL первый параметр является содержимым, а второй - идентификатором. Когда вы вызываете bind_param, вы отменили заказ - попробуйте поменять порядок вокруг в bind_param – andrewsi

ответ

15
$stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?"); 
/* BK: always check whether the prepare() succeeded */ 
if ($stmt === false) { 
    trigger_error($this->mysqli->error, E_USER_ERROR); 
    return; 
} 
$id = 1; 
/* Bind our params */ 
/* BK: variables must be bound in the same order as the params in your SQL. 
* Some people prefer PDO because it supports named parameter. */ 
$stmt->bind_param('si', $content, $id); 

/* Set our params */ 
/* BK: No need to use escaping when using parameters, in fact, you must not, 
* because you'll get literal '\' characters in your content. */ 
$content = $_POST['content'] ?: ''; 

/* Execute the prepared Statement */ 
$status = $stmt->execute(); 
/* BK: always check whether the execute() succeeded */ 
if ($status === false) { 
    trigger_error($stmt->error, E_USER_ERROR); 
} 
printf("%d Row inserted.\n", $stmt->affected_rows); 

Re вопросы:

Я получаю сообщение от моего сценария говорят 0 Вставленные строки

Это потому, что вы изменили порядок параметров, когда вы их связали. Итак, вы ищете столбец id для числового значения вашего $ content, который, вероятно, интерпретируется как 0. Таким образом, предложение WHERE UPDATE соответствует нулевым строкам.

Мне нужно объявить все поля или это нормально, просто обновить одно поле?

Нельзя установить только один столбец в инструкции UPDATE. Другие столбцы не будут изменены.

+0

Что такое первый аргумент в строке 10? –

+0

@AnnonomusPerson: одна буква для каждого параметра. 's' для строки, 'i' для целого числа и т. д. Читайте http://php.net/manual/en/mysqli-stmt.bind-param.php –

+0

'@ BillKarwin' Для меня отображается переменная состояния $ $ значение «целое». Я использовал 'echo $ status', а результат -' 1'. –

1

На самом деле подготовленные заявления не так сложны, как все думают. Совсем наоборот, готовый код на основе инструкций является самым простым и аккуратным способом выполнения запроса. Возьмите, к примеру, свой код.

public function update($content, $id) { 
    $stmt = $this->mysqli->prepare("UPDATE datadump SET content=? WHERE id=?"); 
    $stmt->bind_param('si', $content, $id); 
    $stmt->execute(); 
    return $stmt->affected_rows; 
} 

Как вы можете видеть, код может быть очень простым и лаконичным, если используется правильно!

Вам нужна в основном только три линия:

  1. Подготовить запрос с заполнителями
  2. Затем связать переменные (настройки правильных типов для них первых, где «я» обозначает целое число, «s» для строки и т. д.)
  3. И затем выполнить запрос.

Простой как 1-2-3!

Обратите внимание, что вместо проверки результата каждой функции вручную вы можете set the reporting mode for mysqli раз для всех.Для этого добавьте следующую строку перед mysqli_connect()/new mysqli:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 

результат будет почти так же, как и с trigger_error, но без единой дополнительной строки кода!

Смежные вопросы