L'erreur : Duplicate entry 'X' for key 1

Eléphanteau du PHP | 23 Messages

18 févr. 2011, 20:26

Bonjour,
J'ai sur mon portfolio, deux tables liées, une nommée infographisme contenant mes création et une nommée notesinfo contenant les notes que les visiteurs donnent à ces créations (voir http://lefebvresbook.monespace.net/info ... .php?ID=69 par exemple). Sur la page présentant les créations j'ai un bloc avec un effet lightbox pour donner une note ou modifier la note (si on a déjà voté) celui-ci fonctionne avec les adresses IP.
Lorsque je modifie une note juste après en avoir donné une (sans changer de page entre deux et quasiment uniquement dans ce cas), la page m'affiche Duplicate entry 'X' for key 1 (sachant que X correspond à l'ID)

voici le code du include (le include est sur la page infographisme-details.php, il contient la lightbox modifier la note si le visiteur a déjà noté, l'autre lightbox pour noter ne nous intéresse guère ici)
<?php 
if (isset($_GET['ID'])) {
  $IDgetted = $_GET['ID'];
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>

<body>
<table border="0" cellspacing="0" cellpadding="0" class="lightbox-bloccenter">
<tr>
<td>
<h1>Modifier ma note</h1>
<form action="scripts/editanote-action.php?ID=<?php echo($IDgetted)?>" method="POST" name="editanoteform">
  <b>
  <input type="hidden" name="MM_insert" value="editanoteform" />
  Note :</b>
  <select name="note" id="note">
    <option value="1">01</option>
    <option value="1">01</option>
    <option value="2">02</option>
    <option value="3">03</option>
    <option value="4">04</option>
    <option value="5">05</option>
    <option value="6">06</option>
    <option value="7">07</option>
    <option value="8">08</option>
    <option value="9">09</option>
    <option value="10">10</option>
  </select>&nbsp;<b>/10</b>&nbsp;&nbsp;&nbsp;
  <input type="submit" name="button" id="button" value="Envoyer" />
  <input type="hidden" name="MM_update" value="editanoteform" />
</form>
<a href = "javascript:void(0)" onclick = "document.getElementById('lightbox-editanote').style.display='none';document.getElementById('fade-boxeditanote').style.display='none'">Fermer cette fen&ecirc;tre</a>
</td>
</tr>
</table>
</body>
</html>
et voici le code du script editanote-action.php qui récupère les valeurs et en fais le traitement (page certainement à l'origine du problème) :
<?php require_once('../Connections/portfoliodata.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  if (PHP_VERSION < 6) {
    $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
  }

  $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}
}
// fonction recuperation de l'ip du visiteur
function get_ip(){ 
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){ 
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];} 
elseif(isset($_SERVER['HTTP_CLIENT_IP'])){ 
$ip = $_SERVER['HTTP_CLIENT_IP'];} 
else{ $ip = $_SERVER['REMOTE_ADDR'];} 
return $ip;}$ip = get_ip();
// fin de fonction get_ip
if (isset($_GET['ID'])) {
  $IDgetted = $_GET['ID'];
}
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
  $editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}

if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "editanoteform")) {
  $updateSQL = sprintf("UPDATE notesinfo SET note=%s, ID=%s, IDparentnote=%s, IP=%s WHERE IDparentnote=%s",
                       GetSQLValueString($_POST['note'], "int"),
					   GetSQLvalueString($IDgetted, "int"),
                       GetSQLValueString($IDgetted, "int"),
                       GetSQLValueString($ip, "text"),
                       GetSQLValueString($IDgetted, "int"));

  mysql_select_db($database_portfoliodata, $portfoliodata);
  $Result1 = mysql_query($updateSQL, $portfoliodata) or die(mysql_error());
  

    $editGoTo = '../infographisme-details.php';
  if (isset($_SERVER['QUERY_STRING'])) {
    $editGoTo .= (strpos($editGoTo, '?')) ? "&" : "?";
    $editGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $editGoTo));
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>

<body>
</body>
</html>
Je remercie la communauté de bien vouloir m'aider à solutionner ce problème.
Modifié en dernier par Lefebvresdesigns le 07 juin 2011, 11:23, modifié 1 fois.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

19 févr. 2011, 13:36

C'est quoi la différence entre test champs ID et IDparentnote en base ?
Est-ce normal que tu essayes de mettre la même valeur dans ces deux zones ? L'une d'entre elle ne serait-elle pas une clé primaire dans laquelle tu tentes de renseigner une valeur qui existe déjà en base ?
  $updateSQL = sprintf("UPDATE notesinfo SET note=%s, ID=%s, IDparentnote=%s, IP=%s WHERE IDparentnote=%s",
                       GetSQLValueString($_POST['note'], "int"),
                                           GetSQLvalueString($IDgetted, "int"),
                       GetSQLValueString($IDgetted, "int"),
                       GetSQLValueString($ip, "text"),
                       GetSQLValueString($IDgetted, "int"));
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 23 Messages

19 févr. 2011, 15:25

C'est quoi la différence entre test champs ID et IDparentnote en base ?
Est-ce normal que tu essayes de mettre la même valeur dans ces deux zones ? L'une d'entre elle ne serait-elle pas une clé primaire dans laquelle tu tentes de renseigner une valeur qui existe déjà en base ?
  $updateSQL = sprintf("UPDATE notesinfo SET note=%s, ID=%s, IDparentnote=%s, IP=%s WHERE IDparentnote=%s",
                       GetSQLValueString($_POST['note'], "int"),
                                           GetSQLvalueString($IDgetted, "int"),
                       GetSQLValueString($IDgetted, "int"),
                       GetSQLValueString($ip, "text"),
                       GetSQLValueString($IDgetted, "int"));
Le champ ID c'est la clé primaire comme sur toute table enfin le champ IDparentnote correspond au champ ID de la table infographisme pour lier les tables.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

19 févr. 2011, 16:00

Et es-tu sur que dans ton update tu doives utiliser la même valeur pour alimenter ces deux zones ? :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 23 Messages

19 févr. 2011, 17:06

en fait je pense selon moi qu'ici le champ ID normalement n'a pas besoin d'être alimenté étant donné que le champ ID est déjà dans la clause WHERE ce qui donnerait :
if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "editanoteform")) {
  $updateSQL = sprintf("UPDATE notesinfo SET note=%s, IDparentnote=%s, IP=%s WHERE IDparentnote=%s",
                       GetSQLValueString($_POST['note'], "int"),
                       GetSQLValueString($IDgetted, "int"),
                       GetSQLValueString($ip, "text"),
                       GetSQLValueString($IDgetted, "int"));

  mysql_select_db($database_portfoliodata, $portfoliodata);
  $Result1 = mysql_query($updateSQL, $portfoliodata) or die(mysql_error());
  
mais lorsque je fais comme ceci souvent il me créé un nouvel enregistrement (ce qui fait beuguer car il n'est normalement impossible d'avoir deux notes pour un seul projet ayant la même IP). Je viens tout justement après avoir fait ces modifications d'avoir ce beug, dans phpmyadmin il y avais d'ailleurs plusieurs doublons carrément il m'en a mis plusieurs d'un coup, j'ai donc supprimé les doublons et retente ma chance et là, ça fonctionne ! incroyable je ne sais guère comment cela ce fait mais des fois avec le même code il va mal être interprété par php et les autres fois il va le faire sans soucis, d'où pourrait venir ce problème ?

Eléphanteau du PHP | 23 Messages

19 févr. 2011, 17:11

Serait-ce dû à la qualité de prestations de mon fournisseur d'hébergement ? j'en doute fort

ViPHP
xTG
ViPHP | 7331 Messages

19 févr. 2011, 17:16

il me créé un nouvel enregistrement
Une requête UPDATE ne peut faire cela. Elle met à jour un enregistrement déjà existant.
Ton soucis vient donc d'autre part concernant ce problème.

La qualité de prestations de ton hébergeur ? Je pense plutôt que le soucis n'est pas le serveur mais celui qui tente d'y faire exécuter des codes farfelus. ;)
Comme te l'a fait subtilement remarquer Ryle, tu sembles assez confus sur ce que tu as comme structure et ce que tu dois faire.

Eléphanteau du PHP | 23 Messages

19 févr. 2011, 18:02

oui effectivement ce site web a été conçu au fil du temps pour apprendre php/mysql avec des cas que je peux retrouver sur tous les sites ou presque il a donc constamment subit des modifications et le cadre n'était pas correctement définit à chaque fois si l'on veut on peut décomposer le site en parties qui on le voit parfois on été créés au fur et à mesure de mes besoins car au départ je ne savais pas comment j'allais présenter tout cela. Sinon ben mot de la fin pour le moment le problème est résolut (sous firefox et IE en tout cas) je voulais avoir un point de vue un peut plus poussé et je l'ai : le cadre (ou structure php si on peut se permettre de dire) n'était pas correctement définie du départ afin d'homogénéiser les parties en php/mysql. Je remercie tout de même la communauté d'avoir répondu à mes questions et ferais de mon mieux pour m'améliorer à ce point, je ne suis pas un professionnel comme vous pouvez le voir écris sur le site et donc je ne sais comment établir un plan concret sur le site dès le départ avant même la création c'est un point à revoir mais pour celui-ci je ne savais pas du tout à quoi il ressemblerait du départ. Enfin je souhaite bonne continuation à toute la communauté.