Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Запись в MySQL данных типа SET из HTML Select Multiple

Сообщения:  [1-10]   [11-18] 

 
 автор: Sfinks   (29.10.2013 в 10:10)   письмо автору
 
   для: confirm   (29.10.2013 в 06:52)
 

> Кроме этого он пишет, но не объясняет, что лучше использовать implode().
К сожалению, на такую развернутую лекцию у меня ушло бы минимум часа 2, а-то и 3. Поэтому да, мои ответы чаще всего несколько обрывочны. Спасибо, что дополняете =)

Для danga:
> хотя я добавила в таблицы ключ PRIMARY KEY по столбцу idaupair. Правда, я его добавила в две таблицы - и в members и в hostcountries
Вы не поняли.
В таблице members должен быть первичный ключ по ID мембера.
В таблице countries - по ID страны.
А в таблице соответствий hostcountries - должен быть составной первичный ключ, сразу по двум полям ID мембера и ID страны:
PRIMARY KEY (`idaupair`,`idcountry`)
Тогда можно будет для каждого ID мембера добавить несколько строк с разными ID страны.

  Ответить  
 
 автор: confirm   (29.10.2013 в 06:52)   письмо автору
 
   для: danga   (29.10.2013 в 00:43)
 

Я вам не код дал, а ваше писанное исправил, хотя в вашем писанном явные ошибки, имеется ввиду ссылки на данные. Поэтому и не работает.
Из того что я написал, вам главное, это понять, что я вам уже не первый раз говорю:
1) необходима обязательная проверка данных приходящих извне;
2) экранирование или приведение к типу данных перед занесением их или при использовании их при обращении к базе.

Два этих важных пункта и выполняют первые пять строк кода, а заодно и проверяют пришли ли данные, хотя если вообще полностью, с применением условной записи (тернарного оператора), должно быть так:

<?
//для строковых значений
$var_1 = isset($_POST['var_1']) ? mysql_real_escape_string(trim($_POST['var_1'])) : null;
//для числовых значений
$var_2 = isset($_POST['var_2']) ? (int)$_POST['var_2'] : null;


Такая запись удобна тем, что возвращая форму пользователю при ошибках ввода, в поля ее можно вернуть уже введенные пользователем данные:

<input name=var_1 value="<?=htmlspecialchars($var_1)?>" />
<input name=var_2 value=<?=$var_2?> />


И обязательно обезопасить вывод при выводе строковых значений в браузер - htmlspecialchars(). И применяя такое у себя, вы должны знать, что такая вставка php-переменных в html-код, без конструкции echo, возможна только в том случае, если у вас разрешены короткие РНР теги. Если это не так, то разрешите/включите их, это очень удобно.

Все что выше, это элементарные правила, которые вы просто обязаны выполнять при работе с данными извне.

Сам прием данных описанный выше не будет удобен, в смысле не удобна такая проверка и не возможно проверить все, если данных много, и они представляют собой массив с вложениями, да если еще отключены "магические кавычки" (а это лучше сделать). В этом случае удалить экранирование данных пользователем, убрать крайние пробелы, и если не предвидится возврат данных пользователю, то сразу произвести и экранирование (mysql_real_escape_string), можно так:

<?
//этот код вернет массив $_POST с обработанными указанным способом данными
//готовыми для дальнейшего использования их при работе с базой
array_walk_recursive($_POST, function(&$v) {
    
//здесь можно вообще произвести более сложные проверки входных данных,
    //как например, в зависимости от типа ожидаемых данных
    //сразу приводить их к этому типу  
    
$v mysql_real_escape_string(trim(stripslashes($v)));
});
//используя этот код, необходимо знать, что он будет работать только в версии РНР не ниже 5.3
//так как вместо вызова callback-функции используется замыкание 


PRIMARY KEY которое прописал Sfinks не определяет, что код который я написал, должен обязательно стать рабочим (еще раз говорю, это только исправление вами писанного так, как должно быть "по уму"), это просто применение ключа к полям таблицы, которые нужны для того, чтобы MySQL оптимальнее выполняла свои запросы. Кроме этого он пишет, но не объясняет, что лучше использовать implode(). Это так, легко превратить массив в строку, и даже не просто превратить, а сразу и обработать данные этого массива, например, тоже экранирование их и обрамление кавычками перед записью в базу:

<?
$string 
'"' implode('","'array_map('mysql_real_escape_string'$array)) . '"';


Но нужно знать, что таким образом можно поступить только с одномерным массивом, и с подстановкой не изменяющихся переменных (в его примере это идентификатор полученный после первой записи в базу), но нельзя таким способом превратить в строку данные из разных массивов.

Если вы поняли уже, что такое связанные таблицы и как они связываются (на основе чего), то вся блок схема кода простая:

1. получить данные и проверить их
2. если все обязательные данные получены и они корректные, то запись в базу основных данных (первая таблица)
3. если основных данные записались в базу, то получить идентификатор записи в базу
4. подготовить данные для записи во вторую таблицу
5. записать данные во вторую таблицу связывая их с первой по полученному идентификатору
(здесь надо отметить, что "ждать идентификатор" от записи в первую таблицу, чтобы произвести запись во вторую, это не всегда обязательное условие записи данных в связанные таблицы, но в вашем случае, это именно обязательное условие)
а) в шаге 3 и 5, если произошла ошибка при записи в базу, то вывести сообщение
6. если в шаге 1 ошибка с данными от пользователя (не все получены, или введены некорректно), а также, если массив $_POST пуст (первое обращение к странице), то возвращаем форму пользователю

  Ответить  
 
 автор: danga   (29.10.2013 в 00:43)   письмо автору
 
   для: Sfinks   (28.10.2013 в 08:50)
 

Sfinks и Confirm! Спасибо большое за помощь! очень приятно, что есть добрые и умные люди, кто может помочь. Скрипт Confirma в исходном варианте не работает, хотя я добавила в таблицы ключ PRIMARY KEY по столбцу idaupair. Правда, я его добавила в две таблицы - и в members и в hostcountries. Может это не правильно? Читаю сейчас документацию по MySQL, но что-то я плохо воспринимаю. Нужна практика, за неделю эту науку не постичь... Ну ладно, буду дальше разбираться:)))

  Ответить  
 
 автор: Sfinks   (28.10.2013 в 08:50)   письмо автору
 
   для: danga   (27.10.2013 в 20:33)
 

SHOW CREATE TABLE hostcountries
Должен выглядеть примерно так:
CREATE TABLE `hostcountries` (
 `idaupair` int(10) unsigned NOT NULL,
 `idcountry` int(3) unsigned NOT NULL,
 PRIMARY KEY (`idaupair`,`idcountry`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Тогда можно будет добавить несколько строк для одного пользователя.

В остальном confirm ответил, за исключением того, что вот это:
<?
        $sql 
'INSERT INTO hostcountries (name, idcountry) VALUES '
        foreach(
$hostcountry as $v$sql .= '('.$id.',"'.$name.'",'.$v.'),'
        echo 
mysql_query(rtrim($sql,',')) ? '<center><p><b>Данные добавлены!</b></p></center>'  
                                          
'<center><p><b>Ошибка при добавлении данных!</b></p></center>';
я бы записал так:
<?
  
if($hostcountry){
    
$sql "INSERT INTO hostcountries (idaupair, idcountry) VALUES ($id,".implode("),($id,"$hostcountry).")"
    echo 
mysql_query($sql) ? '<center><p><b>Данные добавлены!</b></p></center>'  
                           
'<center><p><b>Ошибка при добавлении данных!</b></p></center>';
  }
Не люблю циклы.

  Ответить  
 
 автор: confirm   (27.10.2013 в 21:21)   письмо автору
 
   для: danga   (27.10.2013 в 20:53)
 

<?php
//обязательно экранировать нужно строковые данные
//перед занесением их в базу
$name = isset($_POST['name']) ? mysql_real_escape_string($_POST['name']) : null
$surname = isset($_POST['surname']) ? mysql_real_escape_string($_POST['surname']) : null
$email = isset($_POST['email']) ? mysql_real_escape_string($_POST['email']) : null
$gender = isset($_POST['gender']) ? mysql_real_escape_string($_POST['gender']) : null
//а значения списка числа, поэтому их можно приводить к типу integer
$hostcountry array_map('intval'$_POST["hostcountry"]);
//но помнится, что уже еж говорил об этом, о проверке
//и делать надо так:
$hostcountry array_diff(array_map('intval'$_POST["hostcountry"]), array(0));

//если все данные присутствуют
if($name && $surname && $email && $gender && $hostcountry) {
    
$sql 'INSERT INTO members (name, surname, email, gender, hostcountry)  
            VALUES("'
.$name.'", "'.$surname.'","'.$email.'", "'.$gender.'", '.$values.')'//что за $values ?

    //пишем в базу, и пока не запишем удачно это никаких запросов, так как читайте ниже
    
if(mysql_query($sql))  {

        
//второй запрос надо полагать как то связан с первым, то есть таблицы
        //members и hostcountries связаны
        //а значит эта связь должна быть указана во второй таблице 
        //и скорее всего она у вас (если только вы не забыли этого сделать)
        //по идентификатору пользователя, поле которого в таблице должно быть
        //первичным ключом с авто инкрементом
        //то есть перед занесением в базу данных о пользователе, мы этого
        //идентификатора еще не знаем, и только после успешной записи первого запроса
        //получаем этот идентификатор так:  
        
$id mysql_insert_id();
    
        
//вот теперь можно подготавливать второй запрос и делать его
        //но много-строчной записью, всего одним запросом к базе
        
$sql 'INSERT INTO hostcountries (name, idcountry) VALUES ';
        foreach(
$hostcountry as $v$sql .= '('.$id.',"'.$name.'",'.$v.'),';
        
//хотя значение $name в этой таблице совсем не нужно, обращаться к ней
        //вы будете при выборке из первой, а в ней есть имя
        //в этой же таблице нужно идентификатор пользователя и значения которые он выбрал
    
        //ну и завершающий запрос
        
echo mysql_query(rtrim($sql,',')) ? '<center><p><b>Данные добавлены!</b></p></center>' 
                                          
'<center><p><b>Ошибка при добавлении данных!</b></p></center>';   

    } else echo 
'<center><p><b>Ошибка при добавлении данных!</b></p></center>';
    
//вот так, иначе нет смысла в несвязанных таблицах
    //вы же потом из них ничего не получите
} else {
    
//ошибка, не заполнены данные, возвращаем форму для заполнения
}


Всегда форматируйте код свой, делая в нем отступы, если ваш редактор сам этого не умеет делать иначе очень сложно в нем разбираться будет и вам самой.

Применение устаревшего тега center осуждается, хотя небо конечно не рухнет, но выше у вас форма с полем выбора файла позволяющего делать выбор нескольких файлов одним полем (type=file multiple), а это возможно только в современных браузерах, и как-то не вяжется center с этим. )

  Ответить  
 
 автор: danga   (27.10.2013 в 20:53)   письмо автору
 
   для: danga   (27.10.2013 в 20:33)
 

В таблице members столбец hostcountry с типом SET отключен, потому что я не знаю как туда записать массив и сейчас пытаюсь эти данные записать в другую таблицу - hostcountries. Но у меня тоже не получается записать туда несколько строк для одного человека.
Последний вариант скрипта такой, он выдает ошибку придобавлении данных:
<?php
include ('connect.php');
$name $_POST['name'];
$surname $_POST['surname'];
$email $_POST['email'];
$gender $_POST['gender'];
$sql 'INSERT INTO members(name, surname, email, gender, hostcountry) 
VALUES("'
.$name.'", "'.$surname.'","'.$email.'", "'.$gender.'", '.$values.')';

$hostcountry array_map('trim'$_POST["hostcountry"]);

for (
$i=0$i<count($hostcountry); $i++) {
$sql 'INSERT INTO hostcountries(name, idcountry) 
VALUES("'
.$name.'", "'.$values.'")';
}
if(!
mysql_query($sql))
{echo 
'<center><p><b>Ошибка при добавлении данных!</b></p></center>';} 
else 
{echo 
'<center><p><b>Данные добавлены!</b></p></center>';}
?>
<?php
]

  Ответить  
 
 автор: danga   (27.10.2013 в 20:33)   письмо автору
 
   для: danga   (27.10.2013 в 19:08)
 

Проверки на корректоность ввода делаются скриптами JavaScript И PHP, там все нормально. Осталось записать в базу MySQL все до конца.
Для отладки я закачала Apache2.2, MySQL Server5.1, PHP и phpMyAdmin. Базу данных test я сделала в MySQL, а таблицы в phpMyAdmin.

Сейчас у меня 4 таблицы:
1. members
Column Type Collation Attributes Null Default Extra
idaupair int(11) UNSIGNED No None AUTO_INCREMENT
name varchar(30) cp1251_general_ci No None
surname varchar(30) cp1251_general_ci No None
email varchar(30) cp1251_general_ci No None
gender enum('m', 'f') cp1251_general_ci No None
hosrcountry set('1','2','3','4','5','6','7','8','9','10') Yes None

2.hostcountries
idaupair int(11) UNSIGNED No None AUTO_INCREMENT
name varchar(30) cp1251_general_ci No None
idcountry int(3) No None

3. countries
idcountry int(3) UNSIGNED No None AUTO_INCREMENT
country varchar(30) cp1251_general_ci No None

4. photos
idaupair int(11) UNSIGNED No None AUTO_INCREMENT
photo blob BINARY No None
name varchar(30) cp1251_general_ci No None

  Ответить  
 
 автор: danga   (27.10.2013 в 19:08)   письмо автору
 
   для: danga   (27.10.2013 в 18:51)
 

Это конечно не вся анкета, а тест для отладки. Мне осталось научиться записывать и выводить потом из базы фотографии и массивы Select Multiple, все остальное у меня уже получаестя.
Вот такая тестовая HTML форма


<html>
<head>
 <title>Страница управления</title>
</head>
<body>
<form enctype="multipart/form-data" method='post' action='insert.php'>
Name: <input type='text' size='30' name='name'><br>
Famale: <input type='text' size='30' name='surname'><br>
E-mail: <input type='text' size=30 name='email'><br>
Gender:
<input type = "radio" name = "gender" value = "m"> male 
<input type = "radio" name = "gender" value = "f" checked> female
<br>
Host countries:
<select multiple="" name="hostcountry[]" size="4">
<option value="1"> Australia </option>
<option value="2"> Austria </option>
<option value="3"> Belgium </option>
<option value="4"> Canada </option> 
<option value="5"> Denmark </option> 
<option value="6"> Finland </option>
<option value="7"> France </option>
<option value="8"> Germany </option>
<option value="9"> Ireland </option>
<option value="10"> Netherlands</option> 
</select>
<br>
Add photo:<br>
<input type="file" name="photo" multiple accept="image/*,image/jpeg">
<br>
<input type='submit' value='Submit' />
</body>
</html>

  Ответить  
 
 автор: danga   (27.10.2013 в 18:51)   письмо автору
 
   для: Sfinks   (27.10.2013 в 13:44)
 

Изначально я сделала сайт статический ( полностью html), но в нем есть форма регистрации, которую мне пользователи присылают на е-майл. А теперь я хочу сделать, чтобы пользовательские анкеты с фотографиями записывалось в базу, и потом пользователи могли бы выбирать из нее анкеты по критериям и редактировать и удалять свои собственные анкеты. Это вообще мой первый и единственный пока сайт:)))

  Ответить  
 
 автор: Sfinks   (27.10.2013 в 13:44)   письмо автору
 
   для: danga   (27.10.2013 в 13:19)
 

У вас похоже не правильная структура таблицы.

Выполните и покажите результат запроса:
SHOW CREATE TABLE hostcountries

Тоже самое по двум остальным таблицам.

Плюс покажите саму HTML форму и ее пхп-обработчик.

Тогда можно будет что-то сказать.

> А уж как прилепить в эту таблицу user_id из первой таблицы внутри одной операции ввода - это
> вообще для меня загадка. Мне надо это динамическую форму регистрации добавить на готовый
> и работающий статический сайт. Помогите пожалуйста.

Вот этого я вообще не понял. сайт или статический, т.е. состоит из html-файлов, или он динамический, пользуется базой данных и формирует страницы пхп-скриптами.

  Ответить  

Сообщения:  [1-10]   [11-18] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования