2013-08-19 13 views
8

Ciao Sto cercando di imparare il modo corretto di utilizzare le istruzioni preparate per evitare iniezioni SQL, eccPHP UPDATE preparato dichiarazione

Quando eseguo lo script ricevo un messaggio dal mio script dicendo 0 righe inserite, mi aspetto questo per dire 1 file inseriti e, naturalmente, aggiornare la tabella. Non sono completamente sicuro della mia dichiarazione preparata, dato che ho svolto alcune ricerche e intendo che varia da esempio a esempio.

Quando aggiorno il mio tavolo devo dichiarare tutti i campi o è giusto aggiornare solo un campo ??

Qualsiasi informazione sarebbe molto utile.

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> 

classi/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

Hai provato per vedere cosa succede? –

+2

real_escape_string() non è necessario per le istruzioni preparate – Danijel

+2

Nel proprio SQL, il primo parametro è il contenuto e il secondo è ID. Quando chiami bind_param, hai invertito l'ordine: prova a scambiare l'ordine in bind_param – andrewsi

risposta

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 vostre domande:

ricevo un messaggio dal mio script dicendo 0 Righe inserite

Questo perché è stato invertito l'ordine dei parametri quando li hai rilegati. Quindi stai cercando la colonna id per il valore numerico del tuo $ content, che è probabilmente interpretato come 0. Quindi la clausola WHERE di UPDATE corrisponde a zero righe.

ho bisogno di dichiarare tutti i campi o è ok per aggiornare solo un campo ??

È possibile impostare solo una colonna in un'istruzione UPDATE. Altre colonne non saranno cambiate.

+0

Qual è il primo argomento sulla riga 10 per? –

+0

@AnnonomusPerson: una lettera per ogni parametro. 's' per stringa, 'i' per intero, ecc. Leggi http://php.net/manual/en/mysqli-stmt.bind-param.php –

+0

'@ BillKarwin' Per me' $ status variabile' sta mostrando valore "intero". Ho usato 'echo $ status' e l'output è' 1'. –

1

In realtà, le dichiarazioni preparate non sono così complesse come tutti pensano. Al contrario, un codice basato su istruzioni preparate è il modo più semplice e ordinato per eseguire una query. Prendi, ad esempio, il tuo codice.

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; 
} 

Come si può vedere, il codice potrebbe essere molto semplice e conciso, se usato correttamente!

È necessario fondamentalmente solo tre righe:

  1. preparare la vostra query con segnaposto
  2. quindi associare le variabili (impostazione tipi corretti per loro in primo luogo, dove "i" sta per intero, "s" per la stringa e così via)
  3. E quindi eseguire la query.

Semplice come 1-2-3!

Si noti che invece di controllare manualmente il risultato di ogni funzione, è possibile impostare set the reporting mode for mysqli una volta per tutte.Per fare ciò, aggiungere la seguente riga prima mysqli_connect()/new mysqli:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 

il risultato sarà più o meno lo stesso con trigger_error, ma senza una sola riga in più di codice!

Problemi correlati