web-dev-qa-db-fra.com

PHP UPDATE instruction préparée

Salut, j'essaie d'apprendre la bonne façon d'utiliser les instructions préparées pour éviter les injections SQL, etc.

Lorsque j'exécute le script, je reçois un message de mon script disant 0 lignes insérées, je m'attends à ce que cela indique 1 lignes insérées et bien sûr mettre à jour la table. Je ne suis pas tout à fait sûr de ma déclaration préparée, car j'ai fait des recherches et je veux dire que cela varie d'un exemple à l'autre.

Lorsque je mets à jour ma table, dois-je déclarer tous les champs ou est-ce correct de mettre à jour un seul champ ??

Toute information serait très 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>

classes/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);

                                }                   
                            }
18
001221
$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);

Vos questions:

Je reçois un message de mon script disant 0 lignes insérées

En effet, vous avez inversé l'ordre des paramètres lorsque vous les avez liés. Vous recherchez donc dans la colonne id la valeur numérique de votre $ content, qui est probablement interprétée comme 0. La clause WHERE de UPDATE correspond donc à zéro ligne.

dois-je déclarer tous les champs ou est-ce que je peux juste mettre à jour un champ ??

Vous pouvez définir une seule colonne dans une instruction UPDATE. Les autres colonnes ne seront pas modifiées.

28
Bill Karwin

En fait, les déclarations préparées ne sont pas aussi complexes que tout le monde le pense. Bien au contraire, un code basé sur une instruction préparée est le moyen le plus simple et le plus ordonné d'exécuter une requête. Prenez, par exemple, votre code.

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

Comme vous pouvez le voir, le code pourrait être très simple et concis, s'il est utilisé correctement!

Vous n'avez besoin que de trois lignes:

  1. Préparez votre requête avec des espaces réservés
  2. Ensuite, liez les variables (définissez d'abord les types corrects, où "i" signifie entier, "s" pour chaîne, etc.)
  3. Et puis exécutez la requête.

Aussi simple que 1-2-3!

Notez qu'au lieu de vérifier manuellement le résultat de chaque fonction, vous pouvez définir le mode de rapport pour mysqli une fois pour toutes. Pour ce faire, ajoutez la ligne suivante avant mysqli_connect()/new mysqli:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

le résultat sera à peu près le même qu'avec trigger_error mais sans une seule ligne de code supplémentaire!

4