еще раз у меня есть вопрос к hivemind STACKOVERFLOW. Вот сделка, я пытаюсь вставить все мои данные $ _POST из формы в таблицу mysql. Раньше я это делал:
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',)");
где все значения $ были объявлены как $ _POST ['Place'], $ _POST ['Date'] и т. д. Теперь, каждый раз, когда я добавляю новую часть в форму (например, другую текстовую область или что-то еще), я хочу просто необходимо создать новый столбец в mysql вместо добавления другого $ _POST ['foo']. Вот что я пробовал делать:
// 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());
Ошибка, которую я получаю, равна: Количество столбцов не соответствует количеству значений в строке 1. Я понимаю, это означает, что я пытаюсь помещать слишком много данных в базу данных, потому что для данных не хватает столбцов. Я проверил взад и вперед, чтобы узнать, правильно ли я прав (что, я думаю, так и есть). Для справки, вот мой код как для формы, так и для таблицы 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:
Место | Дата | Найти | form_id | who_sponsored | часы | комментарии | howdiditgo | описание | studentleader_name | studentleader_email | имя пользователя
ПРИМЕЧАНИЕ. Я планирую также дезинфицировать данные моего БД / $ POST, но для своих целей я его оставил! Если у вас есть вопросы, не стесняйтесь спрашивать, и я отправлю сюда с EDIT: tags 🙂
Моя функция для этого:
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; }
Не создавайте единственное поле для всех ваших данных … оно отрицает всю ценность в наличии базы данных. Вы теряете всю гибкость при поиске по определенным полям (например, все записи, в которых работало часы, составляет более 25, или дата службы 26 июля 2010 года). Вы можете легко написать функцию, которая построила инструкцию insert из массива значений, аналогичных предоставленный одним Riateche.
Его можно улучшить, переключившись на mysqli и используя переменные bind.
Вот мой:
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 () – это просто оболочка для выполнения инструкции sql. Его называют так:
incomingdump($_POST);
Извините, но у вас почти все не так.
I plan to sanitize my DB contents/$POST data
– НЕПРАВИЛЬНО
Не существует дезинфекции. Существуют только синтаксические правила, которые вы не должны «планировать использовать», но подчиняться безоговорочно . Или вы получите ошибку запроса гораздо раньше, чем при запугивании SQL-инъекций. А с точки зрения базы данных, никакое содержимое БД и данные POST не должны обрабатываться каким-либо особым образом. Это запрос БД, а не содержание, которое вы готовите. И не только данные POST, но и любые данные, поступающие в запрос. Большая разница.
Также обратите внимание, что сама функция mysql_real_escape_string не «санирует» что-либо.
Всестороннюю информацию о правилах построения запросов вы можете найти в этом моем ответе
every time I add a new part to the form
– неправильно.
Добавление нового поля в базу данных не должно быть такой тривиальной задачей, но всегда исключительной проблемой. Перед тем, как начать рисовать какие-либо формы, следует планировать базу данных. И, конечно же, не нужно изобретать механизм для автоматизации такой задачи. Всегда вручную.
$forms = serialize($_POST['service']);
– ТРУДНАЯ НЕПРАВИЛЬНАЯ идея.
Интересно, как такая идея может когда-либо появиться. Mysql, конечно же, не имеет ничего общего с проприетарным форматом сериализации PHP. И даже если бы это было так, – как база данных может сказать, что есть порядковые данные для одного поля или сериализованной строки? Weird.
Единственная разумная точка в вашем вопросе – как упростить создание запросов.
Вот функция, которую я использую:
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); }
это вернет вам инструкцию SET, ограниченную ранее определенным набором полей.
Применение
$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);
или
$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);
Итак, в вашем случае вам нужно добавить только одно слово в список полей