2012-11-21 4 views
2

J'ai donc un problème avec la mise à jour d'une table mysql via mysqli en php.La table de base de données ne se mettra pas à jour avec Mysqli

La connexion de base de données et classe:

<?php 
class testDB extends mysqli { 
    private static $instance = null; 

    private $user = "tester"; 
    private $pass = "tester01"; 
    private $dbName = "testdb"; 
    private $dbHost = "localhost"; 

public static function getInstance() { 
    if (!self::$instance instanceof self) { 
    self::$instance = new self; 
    } 
    return self::$instance; 
} 

public function __clone() { 
    trigger_error('Clone is not allowed.', E_USER_ERROR); 
} 
public function __wakeup() { 
    trigger_error('Deserializing is not allowed.', E_USER_ERROR); 
} 

private function __construct() { 
    parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName); 
    if (mysqli_connect_error()) { 
     exit('Connect Error (' . mysqli_connect_errno() . ') ' 
       . mysqli_connect_error()); 
    } 
    parent::set_charset('utf-8'); 
} 

public function verify_credentials ($username, $password){ 
    $username = $this->real_escape_string($username); 
    $password = $this->real_escape_string($password); 
    $result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'"); 
    return $result->data_seek(0); 
} 

public function get_vitae() { 
    return $this->query("SELECT * FROM vitae"); 

public function update_vitae($text, $id) { 
    $text = $this->real_escape_string($text); 
    $this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id); 
} 
} 
?> 

Voici le code de la page:

Au-dessus de l'en-tête, nous vérifions la connexion en vous assurant il y a une session a commencé; puis importez la classe de base de données et le reste est appelé à soumettre à nouveau le formulaire à cette même page:

<?php 
session_start(); 
if (!array_key_exists("username", $_SESSION)) { 
    header('Location: index.php'); 
    exit; 
} 

require_once("includes/db.php"); 

$vitae_empty = false; 

if ($_SERVER['REQUEST_METHOD'] == "POST") { 
    if ($_POST['text'] == "") { 
     $vitae_empty = true; 
    } else if ($_POST["text"]!="") { 
     testDB::getInstance()->update_vitae($_POST["text"], $_POST["id"]); 
     header('Location: manage.php'); 
     exit; 
} 
} 

?> 

Dans le corps (l'en-tête et le reste du html est importé par un require_once):

<section> 
     <div class="grid_3 header_line"><h2>Update for CV</h2></div> 
     <div class="grid_3"> 
      <?php 
      $result = testDB::getInstance()->get_vitae(); 
      $vitae = mysqli_fetch_array($result);     
      ?> 

      <form name="editvitae" action="editvitae.php" method="POST"> 

       <textarea name="text" rows="50" cols="100"><?php echo $vitae['vitae_text'];?></textarea><br/> 
       <?php if ($vitae_empty) echo "Please enter some text.<br/>";?> 

       <input type="hidden" name="id" value="<?php echo $vitae["vitae_id"];?>" /> <br/> 
       <input type="submit" name="savevitae" value="Save Changes"/> 
      </form> 
     </div> 
     <div class="grid_3"> 
      <p><a href="manage.php">&lsaquo; back to management consol</a></p> 
     </div> 
    </section> 

Après l'étiquette « corps »:

<?php mysql_free_result($result);?> 

Comme vous pouvez le voir tire le texte « vitae » de la base de données, il boucle ensuite sur la même page avec des changements pour mettre à jour la table. Il vérifie également que la zone 'texte' n'est pas vide.

Ce code fonctionne dans une autre application; Je ne comprends pas pourquoi ça ne marchera pas ici. ET avant que vous ne commenciez à m'avertir de l'injection et de la sécurité, j'en ai retiré la plus grande partie en essayant de trouver le problème avec la mise à jour. Il reviendra une fois que je peux comprendre cela.

J'ai essayé de supprimer la vérification de texte; différents noms de variables; déverser les valeurs de publication dans un tableau avant de mettre à jour la base de données; mettre les valeurs de poste dans des variables statiques; vérifier toutes mes orthographes etc ...

Il me manque quelque chose et je sens que ça va être simple.

+0

Dans votre requête UPDATE, vous ne citez pas '$ text'; cela causera des problèmes si vous ajoutez du texte. Mais si vous utilisez mysqli, vous devriez utiliser des paramètres liés, car cela rend votre code beaucoup plus sûr. – andrewsi

+0

@andrewsi Oui, c'est une bonne pratique. 'mysqli :: prepare()' et 'mysqli :: bind_params()' sont une bonne idée. – jpumford

+0

Bien sûr, c'était simple. Merci Andrewsi; votre commentaire a aidé; c'était en m'échappant. – user1843278

Répondre

0

Chaque fois qu'un UPDATE est exécuté via mysqli, vous devez exécuter la méthode $mysqli->commit();.

Votre nouvelle update_vitae serait:

public function update_vitae($text, $id) { 
    $text = $this->real_escape_string($text); 
    $this->query("UPDATE vitae SET vitae_text=".$text." WHERE vitae_id = ".$id); 
    $this->commit; 
} 

mysqli a aussi une fonction de validation automatique qui peut être activé ou désactivé:

$this->autocommit(true); //on 
$this->autocommit(false); //off 
+0

Cela n'est vrai que si vous n'utilisez pas l'autocommit. – andrewsi

+0

Ce qu'il n'est pas, en regardant son code. Je vais ajouter une note à ce sujet, merci. – jpumford

+0

Pas de dés, j'ai ajouté '$ this-> commit;' à la fin de ma fonction de mise à jour et rien. – user1843278

0

La réponse était bien simple. C'était mon échappement sur la chaîne de mise à jour comme Andrewsi suggéré. Voici la mise à jour qui l'a corrigé:

public function update_vitae($text, $id) { 
    $text = $this->real_escape_string($text); 
    $this->query("UPDATE vitae SET vitae_text = '$text' WHERE vitae_id = ".$id); 
} 

Merci pour l'aide! Je conçois des sites Web depuis près de 10 ans, mais je commence tout juste à entrer dans le «vrai» codage PHP au lieu d'utiliser les classes préparées et les fonctions intégrées de dreamweaver. Loin d'apprendre beaucoup mais c'est amusant dans mon temps libre limité.

+0

Oh; et je vais regarder dans les paramètres liés; quoi que ce soit pour simplifier et sécuriser mon code est une bonne chose. – user1843278

0
$result = $this->query("SELECT 1 FROM users WHERE user_username = '" . $username . "' AND user_password = '" . $password . "'"); 

Faites attention à utiliser des AND logiques pour l'authentification de l'utilisateur. Il peut être plus judicieux de valider complètement le nom d'utilisateur avant d'aller chercher un mot de passe. Je dis cela en ce qui concerne les nombreux exemples de personnes qui insèrent -; WHERE 1 = 1 - et les choses comme cela (pas spécifiquement cette déclaration, cependant).Bien sûr, cela peut nécessiter deux requêtes, mais vous devez au moins traiter une seule information pour déterminer si un visiteur est valide. Un autre avantage pourrait être d'économiser le traitement, car vous n'aurez pas à gérer le hachage/cryptage du mot de passe de l'utilisateur dans votre application ou dans la base de données (jusqu'à ce que le nom d'utilisateur ait été vérifié).

Questions connexes