2010-07-26 11 views
3

encore une fois j'ai une question pour le STACKOVERFLOW hivemind. Voici l'affaire, j'essaie d'insérer toutes mes données $ _POST d'un formulaire dans une table mysql. Avant, je ne:

INSERT INTO forms (Place, Date, Find, username, who_sponsored, hours, comments, howdiditgo, studentleader_name, studentleader_email, description) 
VALUES ('$place', '$date','$where', '$username', '$who', '$hours', '$comments', '$how', '$description',)"); 

où toutes les valeurs de $ ont été déclarés comme $ _POST [ 'Place'], $ _POST [ 'Date'], etc. Maintenant, chaque fois que j'ajouter une nouvelle partie à la forme (comme un autre textarea ou quelque chose), je veux juste créer une nouvelle colonne dans mysql au lieu d'ajouter un autre $ _POST ['foo']. Voici ce que j'ai essayé de faire:

// In the previous form, I have set all input ids to "service[]", so all this data would be in a more specific array than just $POST. Turns out all the $_POST['service'] stuff is null... Here's an example: <input name="placeofservice" type="text" id="service[]"> 


$forms = serialize($_POST['service']); 
var_dump($forms); 

mysql_query("INSERT INTO forms VALUES('$forms')") 
or die(mysql_error()); 

L'erreur que je continue à recevoir est: Nombre de colonnes ne correspond pas au nombre de valeurs à la ligne 1. Je sais que cela veut dire que je suis en train de mettre trop de données dans la base de données, car il n'y a pas assez de colonnes pour s'adapter aux données. J'ai vérifié dans les deux sens pour voir si je l'ai bien (ce que, je pense que je fais). Pour référence, voici mon code pour la table de forme et mysql:

<form name="form1" method="post" action="process_form.php"> 
Place of Service</br> 
<input name="placeofservice" type="text" id="service[]"></br> 

Date of Service</br> 
<input name="dateofservice" type="text" id="service[]"></br> 

Where did you find this opportunity?</br> 
<input name="where" type="text" id="service[]"></br> 

What organization sponsored this opportunity?</br> 
<input name="who_sponsored" type="text" id="service[]"></br> 

How many hours did you work?</br> 
<input name="hours" type="text" id="service[]"></br> 

How did it go?</br> 
<input type="text" id="service[]" name="howdiditgo" maxlength="100" /></br> 

Description of Service: 
<textarea name="description" id="service[]" COLS=40 ROWS=6></textarea></br> 

Comments: 
<textarea name="comments" id="service[]" COLS=40 ROWS=6></textarea></br> 

Student Leader Name (If Applicable)</br> 
<input name="studentleader_name" type="text" id="service[]"></br> 

Student Leader Email(If Applicable)</br> 
<input name="studentleader_email" type="text" id="service[]"></br> 
<input type="submit" name="Submit" value="Submit"> 
</form> 

Mysql Tableau:

Place | Date | Trouver | form_id | who_sponsored | heures | commentaires | howdiditgo | description studentleader_name | studentleader_email | nom d'utilisateur

REMARQUE: Je prévois également de désinfecter le contenu de ma base de données/$ POST, mais pour mes besoins, je l'ai omis! Si vous avez des questions, ne hésitez pas à poser et je vais poster ici avec EDIT: balises :)

+1

Vous ne devriez pas avoir à ajouter des données sérialisés à la base de données. Vous voudrez peut-être utiliser une base de données orientée document, comme [Mongo] (http://www.mongodb.org/) – quantumSoup

+0

Il peut simplement rester non sérialisé? –

Répondre

15

Ma fonction pour cela:

function i($table, $array) { 
    $query = "INSERT INTO ".$table; 
    $fis = array(); 
    $vas = array(); 
    foreach($array as $field=>$val) { 
    $fis[] = "`$field`"; //you must verify keys of array outside of function; 
         //unknown keys will cause mysql errors; 
         //there is also sql injection risc; 
    $vas[] = "'".mysql_real_escape_string($val)."'"; 
    } 
    $query .= " (".implode(", ", $fis).") VALUES (".implode(", ", $vas).")"; 
    if (mysql_query($query)) 
    return mysql_insert_id(); 
    else return false; 
} 
6

Ne pas créer un champ unique pour toutes vos données .. Cela annule toute la valeur d'avoir une base de données. Vous perdez toute la souplesse nécessaire pour effectuer des recherches sur des champs spécifiques (par exemple, tous les enregistrements dont les heures travaillées sont supérieures à 25 ou dont la date de service est le 26 juillet 2010) Vous pouvez facilement écrire une fonction qui a construit l'instruction insert à partir d'un tableau similaire à celui que Riateche a fourni.

Il pourrait être amélioré en passant à mysqli et en utilisant des variables de liaison.

-1

Désolé, mais vous avez presque tout faux.

  1. I plan to sanitize my DB contents/$POST data - MAL
    Il n'y a pas une chose appelée aseptisation. Il n'y a que des règles de syntaxe que vous ne devriez pas "prévoir d'utiliser" mais obéissent inconditionnellement. Ou vous vous retrouverez avec une erreur de requête bien plus tôt qu'avec une injection SQL effrayante. Et en termes de base de données, aucun contenu de base de données ni données POST ne doivent être traités d'une manière spéciale. C'est DB requête, pas le contenu que vous préparez. Et pas seulement des données POST, mais des données allant à la requête. La grande différence
    Notez également que la fonction mysql_real_escape_string elle-même ne "nettoie" rien.
    Des informations détaillées sur les règles de construction de requête vous pouvez trouver dans this my answer

  2. every time I add a new part to the form - faux.
    Ajout d'un nouveau champ à la base de données ne devrait pas être une tâche si triviale, mais toujours un problème exceptionnel. Base de données doit être planifiée avant vous avez commencé à dessiner des formulaires.Et, bien sûr, aucun mécanisme ne devrait être inventé pour automatiser une telle tâche. Toujours manuellement.

  3. $forms = serialize($_POST['service']); - TERRIBLE Idée erronée.
    Je me demande comment une telle idée peut jamais arriver. Mysql n'a bien sûr rien à voir avec le format de sérialisation propriétaire de PHP. Et, même si c'était le cas, - comment la base de données peut-elle dire qu'il y a des données ordinales pour une seule ligne ou une rangée sérialisée? Bizarre.

Le seul point sensible de votre question est comment faciliter la création de requêtes.
Voici la fonction que je utilise:

function dbSet($fields, $data = array()) { 
    if (!$data) $data = &$_POST; 
    $set=''; 
    foreach ($fields as $field) { 
    if (isset($data[$field])) { 
     $set.="`$field`='".mysql_real_escape_string($data[$field])."', "; 
    } 
    } 
    return substr($set, 0, -2); 
} 

cela vous renvoie une instruction SET, limitée à l'ensemble précédemment défini des champs.
Utilisation

$fields = explode(" ","name surname lastname address zip fax phone"); 
$query = "INSERT INTO $table SET ".dbSet($fields); 
$result = mysql_query($query) or trigger_error(mysql_error().$query); 

ou

$id  = intval($_POST['id']); 
$fields = explode(" ","name surname lastname address zip fax phone"); 
$query = "UPDATE $table SET ".dbSet($fields)." WHERE id=$id"; 
$result = mysql_query($query) or trigger_error(mysql_error().$query); 

Donc, dans votre cas, vous devez ajouter un seul mot à la liste des champs

+0

@SkyWookie lol. Essayez d'être moins sensible. Il n'y a pas d'arrogance dans ma réponse. Vous êtes drôle en effet :) –

+4

Même si vous ne vouliez pas dire arrogance, votre comportement général à quelqu'un qui apprend PHP est ridicule. Aucun professeur ou assistant décent ne crierait à chaque fois qu'ils voyaient quelque chose qui n'était pas correct ou à leur goût. "Désolé, mon pote" n'a pas aidé non plus. –

+0

mais je suis désolé, je suis un peu crabby, encore le matin ici;) –

0

Voici le mien:

function incomingdump($array){ 
    $tablename="incomingdump"; 

    $currentID = generateID($tablename); 

    $query = "INSERT INTO $tablename (ID) VALUES('$currentID');"; 
    sendquery($query); 
     foreach($array AS $key => $value){ 

     $query = "ALTER TABLE $tablename ADD `$key` VARCHAR(".strlen($value).");"; 
     sendquery($query); 
     $query = "ALTER TABLE $tablename MODIFY `$key`VARCHAR(".strlen($value).");"; 
     sendquery($query); 
     $query = "UPDATE $tablename SET `$key` = '$value' WHERE ID=$currentID"; 
     sendquery($query); 
     } 


} 
function generateID($tablename){ 
    $query = "SELECT count(*) FROM $tablename"; 
    $result = sendquery($query); 
    $row = mysql_fetch_row($result); 
    return $row[0] + 1; 

} 

SendQuery() est juste un wrapper pour l'exécution d'une instruction sql. Son appelé comme ceci:

incomingdump($_POST); 
Questions connexes