Вставка массива HTML-формы $_POST в MySQL с помощью Implode

У меня есть следующая форма отправки html. Эта форма представляет собой PHP_SELF и сохраняет входные данные в виде массива в $_POST.

<html>
<body>
<form method="post" action="<?php echo htmlentities($PHP_SELF); ?>">
<fieldset>
<legend>Direct Bill Information:</legend>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" />
</fieldset>
<input type="submit" value="submit" name="submit" />
</form>
</body>
</html>

У меня есть таблица MySQL с полями 'db_num' и 'db_amnt', и я хочу вставить в таблицу все входные данные из массива. Я осмотрелся, и «взорваться» кажется лучшим способом, но после долгих исследований я все еще не могу заставить его работать. Весь PHP выполняется и завершается без ошибок, однако вместо отображения всех 10 строк обоих столбцов он просто отображает 2 строки двух столбцов со значениями = 0 для всех записей. Это код, который я использую:

$sql2 = array();
foreach($_POST as key=>$value)
{
    if(key != 'submit')
    {   
        if($value != '')
        {   
            $sql2[] = '("'.mysql_real_escape_string($value['db_num']).'", "'.$value['db_amnt'].'")';
        }   
    }
}
mysql_query('INSERT INTO ' .$tablename_db. '(db_num, db_amnt) VALUES '.implode(',', $sql2)); 

Я провел небольшую отладку и повторил $value в цикле foreach, и оказалось, что он отображает только три термина; «Массив», «Массив» и «отправить». Дальнейшие проверки показали, что единственный способ получить значения из формы отправки для отображения — это выполнить цикл foreach через $_POST[db_num] и $_POST[db_amnt] вместо просто $_POST. Я не совсем уверен, почему это происходит и как это исправить. Это мой первый код на PHP, и я учусь на ходу. Я очень ценю любую помощь, которую я могу получить!


person user1562781    schedule 30.07.2012    source источник
comment
Вы делаете ложные предположения о структуре $_POST. Сделайте print_r($_POST), чтобы изучить его и посмотреть, сможете ли вы решить, как исправить скрипт.   -  person Summoner    schedule 30.07.2012
comment
Массивы заканчиваются в данных POST, где, скажем, отправляются флажки. Кроме того, key предположительно должно быть $key. Наконец, плохая идея выгружать данные поста в запрос MySQL. Что, если кто-то изменил DOM или иным образом вмешался в форму? Вы позволяете им потенциально сломать ваш запрос или того хуже. Сделайте надлежащие проверки и проверки.   -  person Mitya    schedule 30.07.2012
comment
Совет: удалите атрибут имени из отправки. Он не несет много полезной информации, поэтому вы не встретите его в своем $_POST.   -  person Paul T. Rawkeen    schedule 30.07.2012


Ответы (2)


попробуй это

$db_num = $_POST['db_num'];
$db_amnt = $_POST['db_amnt'];

$items = array_combine($db_num,$db_amnt);

$pairs = array();

foreach($items as $key=>$value){
  $pairs[] = '('.intval($key).','.intval($value).')';
}

mysql_query('INSERT INTO ' .$tablename_db. '(db_num, db_amnt) VALUES '.implode(',',$pairs));
person voodoo417    schedule 30.07.2012

После отправки ваша html-форма будет генерировать следующий массив $_POST (я создам несколько образцов значений).

$_POST = [
    'db_num' => ['1', '2',  '3',  '4',  '5',  '6', '7', '8', '9', '10'],
    'db_amnt' => ['100', '125', '150', '175', '200', '225', '250', '275', '300', '325']
];

Другими словами, $_POST['db_num'] будет иметь $_POST['db_num'][0], удерживающего 1, вплоть до $_POST['db_num'][9], удерживающего 10. Точно так же $_POST['db_amnt'][0] будет содержать 100, $_POST['db_amnt'][1] будет содержать 125 и так далее. Даже если пользователь не заполнит одно из полей, все равно будет отправлено пустое поле, а значением будет строка нулевой ширины (пустая строка).

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

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

$conn = new mysqli($server, $user, $password, $database);
$stmt = $conn->prepare("INSERT INTO {$tablename_db} (db_num, db_amnt) VALUES (?,?)");
$stmt->bind_param("ii", $num, $amnt);  // name the two variables which will pass integer values where the ?'s are located
foreach ($_POST['db_num'] as $index => $num) {
    $amnt = $_POST['db_amnt'][$index];
    if (strlen($num) && strlen($amnt)) {
        $stmt->execute();  // only INSERT qualifying rows
    }
}

Обратите внимание: если ваши значения db_amnt имеют десятичные разряды (это числа с плавающей запятой), вы можете изменить i в вызове bind_param() на d. Некоторые люди предпочитают простейший способ объявления всех значений как s (строка), но мне нравится ограничивать его при работе с предсказуемым пользовательским вводом.

Вот демонстрация метода повторения.

Если у вас есть другие проверяющие проверки, просто добавьте их в мое выражение if.

Если вы хотите насладиться индивидуальной проверкой успеха, вы можете написать что-нибудь сразу под execute(), чтобы сослаться на затронутые строки.

Повторное использование подготовленного оператора является одним из двух способов, которыми этот процесс должен выполняться с помощью mysqli. Другой включает в себя создание одного всеобъемлющего запроса INSERT со всеми строками в нем, но требует немного большей подготовки. Эти два метода mysqli безопасны для инъекций, стабильны и эффективны.

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

person mickmackusa    schedule 02.01.2020