#php #mysql #html #drop-down-menu #associative-array
#php #mysql #HTML #выпадающее меню #ассоциативный массив
Вопрос:
У меня возникла проблема с попыткой добавить «количество» к продукту, который заказывает пользователь. У меня есть таблица Products, таблица orders, таблица order_item (которая представляет собой таблицу «многие ко многим», содержащую идентификаторы как продуктов, так и заказов). У меня есть выпадающее окно слева, в котором указано нужное вам количество. Максимальное значение — это запас, доступный в системе.
Вот как выглядит форма:
<form name ="order_form" method="post" action="add_order_action.php" enctype="multipart/form-data">
<table border=1 cellpadding=2 cellspacing=2>
<caption>Order Form</caption>
<tr>
<th align="right"> Property </th>
<th align="left"> Value </th>
</tr>
<tr>
<td class="col1"> Name </td>
<td class="col2"> <input type="text" name="customer" id ="customer" size=30> </td>
</tr>
<tr>
<td class="col1"> Address </td>
<td class="col2"> <input type="text" name="address" id ="address" size=30> </td>
</tr>
<tr>
<td class="col1"> Products </td>
<td class="col2">
<!-- Interests is an array of all interests in the database-->
{foreach $products as $product}
<select name="products[{$product.id}][quantity]" id ="quantities">
{section name=quantities start=0 loop=$product.stock 1 step=1}
<option value="{$smarty.section.quantities.index}">{$smarty.section.quantities.index}</option>
{/section}
</select>
<input type="checkbox" name="products[{$product.id}][is_checked]" value="1">{$product.name}<br>
{/foreach}
</td>
</tr>
<tr>
<td colspan=2 align="center">
<input type="submit" name="submit" value="Submit">
<input type="reset" name="reset" value="Reset">
</td>
</tr>
</table>
</form>
Названия продуктов и номера запасов взяты из таблицы products:
create table if not exists SEProducts
(
id int not null auto_increment primary key,
price double not null,
name varchar(30) not null,
stock int not null,
original_stock int not null,
sold_stock int not null
)ENGINE=INNODB;
Теперь, что я делаю, так это создаю массив из названий продуктов, которые отмечены. Что я хочу сделать, так это связать значения из выпадающих меню, НО ТОЛЬКО ЕСЛИ ОНИ ЯВЛЯЮТСЯ ОДНИМ ИЗ ОТМЕЧЕННЫХ ЗНАЧЕНИЙ. Кроме того, если значение установлено, количество не может быть равно 0. Вероятно, я делаю это крайне неприятным способом, но это то, что я считал лучшим. Я мог бы создать текстовое поле, но тогда вам пришлось бы очищать пользовательский ввод. Это было бы нормально, если бы это работало, в отличие от этого, которое не работает =/
Я добавляю заказы, получая массив product:
<?php
include "includes/defs.php";
$customer = $_POST['customer'];
$delivery_address = $_POST['address'];
if (isset($_POST['products']))
{
$products = $_POST['products'];
}
else
{
$error = "An order must consist of 1 or more items.";
header("Location: list_inventory.php?error=$error");
exit;
}
$id = add_order($customer, $delivery_address, $products);
header("Location: order.php?id=$id");
exit;
?>
Тогда моя функция добавления заказа работает следующим образом:
function add_order($customer, $delivery_address, $products)
{
$connection = mysql_open();
$customer = mysql_escape_string($customer);
$delivery_address = mysql_escape_string($delivery_address);
$query = "insert into SEOrders (name, address, status) " .
"values ('$customer', '$delivery_address', 'New')";
$result = mysql_query($query, $connection) or show_error();
$id = mysql_insert_id();
foreach ($products as $product)
{
if ($product['is_checked'] != 0 amp;amp; $product['quantity'] != 0)
{
$query2 = "insert into SEOrder_items (order_id, product_id, quantity) " .
"values ('$id', '$product.id', '$product.quantity')";
$result2 = mysql_query($query2, $connection) or show_error();
}
}
mysql_close($connection) or show_error();
return $id;
}
Я думал, что мне, возможно, придется использовать какой-нибудь JavaScript, но я абсолютно профан в этом.
Если бы я не смог объяснить сам: Короче говоря; Мне нужно добавить количества в массив products, но только если продукты проверены и количество равно > 0.
Заранее спасибо, приветствую 🙂
РЕДАКТИРОВАТЬ: Я внес некоторые изменения, но теперь я получаю следующую ошибку: Ошибка 1452: Не удается добавить или обновить дочернюю строку: сбой ограничения внешнего ключа ( db/SEOrder_items
, ССЫЛКИ на ОГРАНИЧЕНИЕ SEOrder_items_ibfk_2
ВНЕШНЕГО КЛЮЧА ( product_id
) SEProducts
( id
))
Ответ №1:
В качестве первого шага я бы объединил массивы продуктов и количеств, чтобы количества, флажок и название продукта были в одном массиве:
<select name="products[{$product.id}][quantity]" id ="quantities">
…
</select>
<input type="checkbox" name="products[{$product.id}][is_checked]" value="1" />
приведет к следующему массиву (где 1 и 2 — идентификаторы продуктов, ‘is_checked’ устанавливается только в том случае, если флажок был установлен):
$_POST['products'] = array(
[1] => array(
'quantity' => 3,
'is_checked' => 1,
),
[2] => array(
'quantity' => 1,
// not checked
),
);
Должно быть легко пройти через такой массив, используя:
foreach($_POST['products'] as $currentProductId => $currentProductArray)
Комментарии:
1. Я внес эти изменения, но теперь, когда я пытаюсь добавить новый порядок, я получаю следующую ошибку: Ошибка 1452: Не удается добавить или обновить дочернюю строку: сбой ограничения внешнего ключа (
db/SEOrder_items
, ССЫЛКИ на ОГРАНИЧЕНИЕSEOrder_items_ibfk_2
ВНЕШНЕГО КЛЮЧА (product_id
)SEProducts
(id
))
Ответ №2:
Я думаю, вам просто нужно немного подправить вашу логику и ваш шаблон.
Во-первых, вы хотите полностью использовать продукты, доступные на странице заказа, а не продукты, которые возвращаются; это:
if (isset($_POST['products']))
{
$products = $_POST['products'];
}
else
{
$error = "An order must consist of 1 or more items."
header("Location: list_inventory.php?error=$error");
exit;
}
Должно выглядеть примерно так:
$products = the_products_list_that_you_sent_to_the_page();
Конечно, если список продуктов большой, то вам придется вытаскивать список продуктов со страницы (и проверять каждый продукт), как вы делаете сейчас. Однако, если список продуктов невелик, то проще начать с известного и допустимого списка.
Суть проблемы заключается в вашем взаимодействии с базой данных и в том, как add_order
это работает. Вы add_order
получите список продуктов для просмотра в $products
. Все, что вам нужно сделать, это:
- Создайте массив данных для вставки.
- Пройдите
$products
, если продукт отмечен и у него есть количество, добавьте его и его количество в список. - Проверьте, есть ли что-нибудь в списке заказов после завершения вышеупомянутого цикла:
- Если в списке заказов что-то есть,
add_order
можете добавить все это в базу данных. - Если в списке заказов ничего нет,
add_order
может вернуть код ошибки (например, нулевой идентификатор заказа), и вызывающий может пожаловаться пользователю, что вообще ничего не заказывать не имеет смысла.
- Если в списке заказов что-то есть,
Основная стратегия заключается в сборе ваших данных и последующем действии с ними, а не в попытке действовать с вашими данными во время их сбора.
Теперь возникает проблема: как нам связать количество с конкретной проблемой? Это легко решить, поскольку у нас есть идентификаторы продуктов; ваши <select>
элементы должны быть:
<!--
Note that this also avoids the evil of having
duplicate id attributes in one page
-->
<select name="quantity_{$product.id}">
Затем, когда вы ищете количество определенного продукта, вы можете извлечь его прямо из $_POST
как скаляр as $q = $_POST['quantity_' . $product_id]
.
Я знаю, что мог бы решить корень вашей проблемы, просто посоветовав вам переименовать ваши <select>
элементы, но я решил, что по ходу дела разберусь с некоторыми другими вашими возможными проблемами.