Консультация № 173356
17.10.2009, 15:21
0.00 руб.
0 13 2
Из формы (16 полей) получаю массив $_POST

В форме 11 полей обязательных и 5 нет т. е от 1 до 5 полей могут прийти пустыми.

В скрипте я создаю таблицу
Код:
]<?php
// создаём таблицу
$CT_UTK="CREATE TABLE IF NOT EXISTS `$USER_TABLE_KOMAND`
(id INT NOT NULL AUTO_INCREMENT, id1 TEXT, id2 TEXT, id3 TEXT, id4 TEXT, id5 TEXT, id6 TEXT, id7 TEXT, id8 TEXT, id9 TEXT, id10 TEXT, id11 TEXT, id12 TEXT, id13 TEXT, id14 TEXT, id15 TEXT, id16 TEXT, PRIMARY KEY ( `id` ))";
mysql_query ($CT_UTK) or die (mysql_error());
?>


Теперь в эту таблицу надо внести данные из $_POST, но что делать с путыми переменными? Притом их кол-во варьируется от 1 до 5.
Мне посоветовали в динамически создавать запрос INSERT INTO с помощью цикла который поможет не включать пустые переменные в запрос, но я не знаю как это реализовать:(

Пробовал просто присвоить пустой перменной null

Код:
if (empty($_POST[S5]))
{$_POST[S5] = null;}
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (id1, id2, id3, id4, id5, id6, id7, id8, id9, id10, id11, id12, id13, id14, id15, id16)
VALUES(".$Gk.", ".$Ld.", ".$Cd1.", ".$Cd2.", ".$Rd.", ".$Lm.",".$Cm1.", ".$Cm2.",".$Rm.",".$Cf1.", ".$Cf2.", ".$S1.", ".$S2.",".$S3.", ".$S4.",".$S5.")";
mysql_query ($II_UTK) or die (mysql_error());


но SQL всё равно ругается:( (You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2)

Помогите, пожалуста решить эту беду:)

Обсуждение

Неизвестный
17.10.2009, 16:03
общий
это ответ
Здравствуйте, Olegarh3000.
SQL запрос это простой текст, вы же переменной присваиваете null, но в запрос она должна попадать как 'null', т.е. строка.
Поэтому присваивайте переменной именно строку со значением 'null'
P.S. При вставке в текстовые поля значения должны быть заключены в одинарные кавычки, если это не null. Если есть данные, то вы должны заключить их в кавычки, если нет, то переменной присвойте строковое значение 'null'

Приложение:
if (empty($_POST[S5])){
$S5 = "null";
} else {
$S5= "'".$_POST[S5]."'";
}
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (id1, id2, id3, id4, id5, id6, id7, id8, id9, id10, id11, id12, id13, id14, id15, id16)
VALUES($Gk,$Ld,$Cd1,$Cd2,$Rd,$Lm,$Cm1,$Cm2,$Rm,$Cf1,$Cf2,$S1,$S2,$S3,$S4,$S5)";
mysql_query ($II_UTK) or die (mysql_error());
5
Спасибо за профессиональное разьяснение!
Неизвестный
17.10.2009, 19:43
общий
Selax:
Иногда форумы помогают, а иногда и запутывают. В данном случае меня как новичка сбили с толку и пришлось долго мучаться:) Если бы мне так раньше обьяснили:)
Я решил проблему изменив запрос, а именно - сменил вид ковычек, выкинул к чёрту эту конкатенацию (я раньше как раз делал без неё, по учебнику с правильным синтаксисом, правда с другими ошибками:)). Вот мой код полностью:

Код:
<?php
session_start();
include_once("include/connectdb.php");
include('include/user_register/uni-auth.php');

if (USER_LOGGED){
if (empty($_POST ['namekomand']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['namekomand']))
{echo '<h1 align="center">Имя команды не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Gk']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST['2Gk']))
{echo '<h1 align="center">id 1-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Ld']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Ld']))
{echo '<h1 align="center">id 2-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cd1']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['Cd1']))
{echo '<h1 align="center">id 3-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cd2']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Cd2']))
{echo '<h1 align="center">id 4-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Rd']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Rd']))
{echo '<h1 align="center">id 5-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Lm']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Lm']))
{echo '<h1 align="center">id 6-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cm1']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Cm1']))
{echo '<h1 align="center">id 7-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cm2']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Cm2']))
{echo '<h1 align="center">id 8-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Rm']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Rm']))
{echo '<h1 align="center">id 9-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cf1']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Cf1']))
{echo '<h1 align="center">id 10-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (empty($_POST['2Cf2']) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2Cf2']))
{ echo '<h1 align="center">id 11-го игрока не задано или ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2S1']))
{ echo '<h1 align="center">id 12-го игрока ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2S22']))
{ echo '<h1 align="center">id 13-го ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2S3']))
{ echo '<h1 align="center">id 14-го ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2S4']))
{ echo '<h1 align="center">id 15-го ЗАДАНО НЕВЕРНО!!!</h1>';}
else if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST ['2S5']))
{ echo '<h1 align="center">id 16-го ЗАДАНО НЕВЕРНО!!!</h1>';}
else {
$NameKomand = mysql_real_escape_string(substr(iconv("UTF-8", "WINDOWS-1251", $_POST ['namekomand']),0,20);
$Gk = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Gk']));
$Ld = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Ld']));
$Cd1 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cd1']));
$Cd2 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cd2']));
$Rd = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Rd']));
$Lm = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Lm']));
$Cm1 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cm1']));
$Cm2 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cm2']));
$Rm = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Rm']));
$Cf1 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cf1']));
$Cf2 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2Cf2']));
$S1 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2S1']));
$S2 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2S2']));
$S3 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2S3']));
$S4 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2S4']));
$S5 = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST ['2S5']));
//задаём уникальное имя для таблицы с матчами: имя пользователя + имя его команды
$USER_TABLE_KOMAND = $UserName.$NameKomand;
// создаём таблицу
$CT_UTK = "CREATE TABLE IF NOT EXISTS `$USER_TABLE_KOMAND` (id INT NOT NULL AUTO_INCREMENT, id1 TEXT, id2 TEXT, id3 TEXT, id4 TEXT, id5 TEXT, id6 TEXT, id7 TEXT, id8 TEXT, id9 TEXT, id10 TEXT, id11 TEXT, id12 TEXT, id13 TEXT, id14 TEXT, id15 TEXT, id16 TEXT, PRIMARY KEY ( `id` ))";
mysql_query ($CT_UTK) or die (mysql_error());
// добавляем запись в таблицу
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (id1, id2, id3, id4, id5, id6, id7, id8, id9, id10, id11, id12, id13, id14, id15, id16)
VALUES('$Gk', '$Ld', '$Cd1', '$Cd2', '$Rd', '$Lm','$Cm1', '$Cm2','$Rm','$Cf1', '$Cf2', '$S1', '$S2','$S3', '$S4','$S5')";
mysql_query ($II_UTK) or die (mysql_error());
echo '<h1 align="center">Ваш состав сохранён!</h1>';}}
else{
echo '<h1 align="center">Вы не авторизованы!</h1>

<h2 align="center">Зарегистрируйтесь или войдите в систему под своим Логином!!!</h2>';
}
?>


Если можете, посоветуйте, что улучшить или изменить или как то усилить защиту?
Неизвестный
17.10.2009, 19:55
общий
это ответ
Здравствуйте, Olegarh3000.
Во-первых. Начнем с Вашего запроса для вставки данных. Вы вставляете текст и при этом не берете его в кавычки. Отсюда и появляется Ваша ошибка.
Если на то пошло то запрос должен быть таким:
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (id1, id2, id3, id4, id5, id6, id7, id8, id9, id10, id11, id12, id13, id14, id15, id16)
VALUES('".$Gk."', '".$Ld."', '".$Cd1."', '".$Cd2."', '".$Rd."', '".$Lm."','".$Cm1."', '".$Cm2."','".$Rm."','".$Cf1."', '".$Cf2."', '".$S1."', '".$S2."','".$S3."', '".$S4."','".$S5."')";
Далее если Вы хотите не заполнять некоторые поля, то вам либо при создании нужно указать им NULL либо сделать DEFAULT. В этом случае MySQL не будет ругаться на то что вы пытаетесь оставить поля незаполненными.
советую почитать документацию по MySQL http://dev.mysql.com/doc/refman/5.1/en/create-table.html
И наконец последнее. То что Вы делаете, то есть загоняете сразу напрямую необработанные данные в запрос является кощунством и открытой дырой для взлома базы данных. Для того чтобы этого избежать советую хотя бы обрабатывать все данные php функцией addslashes();

В итоге у Вас должно получиться чтото вроде такого:


Приложение:
$i=1;
foreach($_POST as $value) {
$rows[] = 'id'.$i;
$values[] = '"'.addslashes($value).'"';
}
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (".implode(",", $rows).") VALUES (".implode(",", $values).")";
4
Ответ привилен и доходчиво обьяснён, но вот с советами типа "То что Вы делаете, то есть загоняете сразу напрямую необработанные данные в запрос является кощунством и открытой дырой для взлома базы данных" не видя весь код, лучше не спешить. <br>Также и "советую почитать документацию по MySQL http://dev.mysql.com/doc/refman/5.1/en/create-table.html" для новичков не совсем полезен: <br>1. Не все знают английский<br>2. Не все и с русской документацией умеют работать<br>Лучше посоветовали по какой книге Вы учились и с чего начинали:)
Неизвестный
17.10.2009, 20:04
общий
Забыл в ответе делать инкремент i
foreach($_POST as $value) {
$rows[] = 'id'.$i;
$values[] = '"'.addslashes($value).'"';
$i++;
}
вот так
Неизвестный
17.10.2009, 20:13
общий
Olegarh3000:
На первый взгляд вроде более менее нормально. Но я бы заменил кучу if'ов на один в цикле. Примерно:
$keys= array('namekomand','2Gk','2Ld',...);
$check= true;
foreach ($keys as $key){
if (empty($_POST [$key]) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST [$key])) {
echo '<h1 align="center">Параметр задан неверно</h1>';
$check = false;
break;
}
}
if ($check){ работа с БД}
Можно список ключей сделать расширенным:
$keys= array(
array('key'=>'namekomand','note'=>'Имя команды'),
array('key'=>'2Gk','note'=>'id 1-го игрока'),
.....
);
Тогда можно при проверке обращаться как $key['key'], а в выводе сделать echo 'Параметр'.$key['note']." задан неверно"
Неизвестный
17.10.2009, 23:35
общий
Selax:
Заменил IF-ы:
Код:
if (USER_LOGGED){
$keys = array(
array('key'=>'namekomand','note'=>'Ваша команда'),
array('key'=>'2Gk','note'=>'id 1-го игрока'),
array('key'=>'2Ld','note'=>'id 2-го игрока'),
array('key'=>'2Cd1','note'=>'id 3-го игрока'),
array('key'=>'2Cd2','note'=>'id 4-го игрока'),
array('key'=>'2Rd','note'=>'id 5-го игрока'),
array('key'=>'2Lm','note'=>'id 6-го игрока'),
array('key'=>'2Cm1','note'=>'id 7-го игрока'),
array('key'=>'2Cm2','note'=>'id 8-го игрока'),
array('key'=>'2Rm','note'=>'id 9-го игрока'),
array('key'=>'2Cf1','note'=>'id 10-го игрока'),
array('key'=>'2Cf2','note'=>'id 11-го игрока'));

$keys2 = array(
array('key'=>'2S1','note'=>'id 12-го игрока'),
array('key'=>'2S2','note'=>'id 13-го игрока'),
array('key'=>'2S3','note'=>'id 14-го игрока'),
array('key'=>'2S4','note'=>'id 15-го игрока'),
array('key'=>'2S5','note'=>'id 16-го игрока'));

$check= true;
foreach ($keys as $key){
if (empty($_POST [$key['key']]) || preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST [$key['key']])) {
echo '<h2 align="center">Параметр «'.$key['note'].'» пуст или <u>задан неверно</u>!</h2>';
$check = false;
break;
}
}
foreach ($keys2 as $key2){
if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/", $_POST [$key2['key']])) {
echo '<h2 align="center">Параметр «'.$key2['note'].'» <u>задан неверно</u>!</h2>';
$check = false;
break;
}
}
if ($check){

Даже добавил автоматическую обработку функциями:

Код:
foreach ($_POST as $key3){
mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST [$key3]));
}

Правильно?
Как говорится, лучше один раз увидеть и попробывать, чем сто раз услышать:)
Неизвестный
17.10.2009, 23:53
общий
freedayko:
Код:

$i=1;
foreach($_POST as $value) {
$rows[] = 'id'.$i;
$values[] = '"'.addslashes($value).'"';
$i++;
}
$II_UTK = "INSERT INTO `$USER_TABLE_KOMAND` (".implode(",", $rows).") VALUES (".implode(",", $values).")";

Ваш код очень познователен, порывшись в гугле, я так и не нашёл чего то подобного, как формировать в цикле запрос. Огромное спасибо!!!
Но в моём коде есть нюанс!
В массиве $_POST присутствует элемент 'namekomand', который в таблицу заноситься не должен!

Возможен ли переделать ваш цикл с учётом этого нюанса?
Неизвестный
18.10.2009, 00:30
общий
Olegarh3000:
тогда нам нужно иметь массив названий полей. причем можно одномерный.
Например
$fields = array('field1', 'field2', 'field3');
for ($i = 0; $i < count($fields); $i++) {
if (isset($_POST[$fields[$i]]) {
$rows[] = 'id'.($i+1);
$values[] = '"'.addslashes($_POST[$fields[$i]]).'"';
}
}
Дальше можно играться, устанавливать еще всякие параметры полям. Например у меня форма в свое время генерировалась сама как раз по такому массиву.

З.Ы. Годы работы программистом в этой области дают о себе знать. Вот и некоторые тактики свои появляются
З.З.Ы. Я дал ссылку по которой сам учился. Для меня как раз два основных источника информации это http://www.php.net и http://dev.mysql.com/doc/ Там кстати есть и на русском. Кроме того можно всегда посмотреть как phpmyadmin создает запросы. Вообще сделал вывод о том что данные не обрабатываются действительно поспешно. К сожалению и на сегодня достаточно молодых людей которые кидают в базу без обработки. Кстати советую Вам если вы строите какуюто новую систему а не переделываете существующее, то использовать какой-либо MVC фреймворк. например CodeIgniter, Kohana, CakePHP, Symfony и много других. Они гораздо облегчат ваш труд по построению таблиц, форм и отлову ошибок. И вообще советую немножко узнать про технологию MVC
Неизвестный
18.10.2009, 00:47
общий
Olegarh3000:
Вроде правильно. Но я бы перед вторым foreach ($keys2 as $key2) добавил бы проверку на $check
if ($check){foreach ($keys2 as $key2){.....}}
Это если первая проверка не прошла, то вторую как-бы и не зачем делать ;)
Неизвестный
18.10.2009, 01:12
общий
freedayko:
Спасибо за супер развёрнутый ответ:)
В том то и дело что строю систему с нуля, поэтому много вопросов. Также поджимают сроки, поэтому познакомиться с фреймворками не успеваю. Читал про CodeIgniter, вроде понравился, но эксперементировать буду уже после запуска проекта. Сегодня решил последнюю загвоздку, код полностью теперь рабочий. Вот оптимизирую по ходу, хочу правда ещё одну фишку реализовать для удобства, но не критично. Форма у меня будет видимо передавать данные Ajax'ом , там тоже есть фреймворки для проверки форм, надо вот и сними познакомиться.
Вы вот применяете функцию addslashes() , я вроде читал, что mysql_real_escape_string() новее и практичнее, как вы считаете?
Неизвестный
18.10.2009, 01:25
общий
Olegarh3000:
Да. Действительно новей и практичней. Это я по старинке написал. Для примера. Просто для этой задачи в последнее время пользуюсь обычно методами фреймворка и как то не сильно задаюсь данным вопросом. ) Хотя судя по всему она делает тоже самое. Но средствами уже библиотеки MySQL. Наверно действительно лучше )
Неизвестный
18.10.2009, 12:56
общий
Selax:
чойто конструкция не работает, по крайней мере элемент $_POST ['namekomand'] не подвергся обработке функцией iconv

Код:
<?php
foreach ($_POST as $key3){
mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $_POST [$key3]));
}?>
Неизвестный
18.10.2009, 22:55
общий
Selax:
Ужо разобралсо
Код:
foreach ($_POST as $key => $value) {
$value = mysql_real_escape_string(iconv("UTF-8", "WINDOWS-1251", $value));
$_POST[$key] = $value;
}
Форма ответа