我正在尝试创建订单/发票系统。
我有一个用于orders
的表和一个用于行项orders_items
的表。
我正在尝试使用PDO::ATTR_EMULATE_PREPARES
属性一次性插入所有订单项。
我了解安全风险,此数据库中没有用户输入。这一切都在幕后。
当我通过$order_item
数组进行解析时,我正在使用占位符创建多个INSERT sql语句。
但是,当我绑定参数时,在数据库中似乎仅添加了$order_item
数组中的最后一项。
这是$data
变量寻找$order_item
数组的方式。
array(2) {
[0]=>
array(4) {
["name"] => string(8) "A red item"
["quantity"]=> int(1)
["price"] => string(1) "1"
["order_id"]=> string(2) "44"
}
[1]=>
array(4) {
["name"] => string(9) "A blue item"
["quantity"]=> int(1)
["price"] => string(1) "2"
["order_id"]=> string(2) "44"
}
}
Build Insert语句将创建以下内容:
INSERT INTO orders_items ( name, quantity, price, order_id ) VALUES ( :name, :quantity, :price, :order_id );
INSERT INTO orders_items ( name, quantity, price, order_id ) VALUES ( :name, :quantity, :price, :order_id );
在占位符-值绑定阶段,我要做的是:
:name = "A red item", :quantity = 1, :price = 1, :order_id = 44
:name = "A blue item", :quantity = 1, :price = 2, :order_id = 44
但是只有这一个被插入数据库:
:name = "A blue item", :quantity = 1, :price = 2, :order_id = 44
这是我的创建功能
public static function create ($data = []) {
$order_info = $data['order_info'];
$orderID = //do first insert and get the record ID
$order_item = $data['order_item'];
//Attach the order number to the each item in the $order_item array
//This way during the SQL for each, the order_id, which is a required column, will be added
foreach ($order_item as $key=>$value){
$order_item[$key]["order_id"] = $orderID;
}
//Build the INSERT statements
$sql = "";
foreach ($order_item as $item){
$sql .= "INSERT INTO orders_items ";
$sql .= " ( " . implode(", ", array_keys($item)) . " )";
$sql .= " VALUES ( :" . implode(", :", array_keys($item)) . " ); ";
}
$db = static::getDB();
$db->setAttribute( PDO::ATTR_EMULATE_PREPARES, 1 );
$stmt = $db->prepare( $sql );
//BIND ALL THE ORDER ITEM PLACEHOLDERS TO THEIR VALUES.
foreach ($order_item as $item) {
foreach ($item as $linekey => $linevalue) {
$stmt->bindValue(":" . $linekey, $linevalue, PDO::PARAM_STR);
}
}
return $stmt->execute();
}
我在做什么错?这可能吗?有更好的方法吗?
答案 0 :(得分:1)
我会这样做,这要简单得多:
<div class="product-descriptions">
<div class="product-descriptions__item">
<div class="product-descriptions__icon-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 70" aria-hidden="true" focusable="false">
<title>icon_circleplus</title>
<g>
<path d="M50.66,4.76a30.71,30.71,0,1,0,30.7,30.7,30.71,30.71,0,0,0-30.7-30.7M66.55,38.87H54.06V51.35H47.25V38.87H34.76V32.06H47.25V19.57h6.81V32.06H66.55Z"></path>
</g>
</svg>
</div>
<div class="product-descriptions__title">Advantage SafeBalance</div>
<div class="product-descriptions__description">Say goodbye to paper checks—and to overdraft fees.</div>
<a id="" class="product-descriptions__link" href="#" data-index="0">
See details
</a>
</div>
<div class="product-descriptions__item">
<div class="product-descriptions__icon-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 70" aria-hidden="true" focusable="false">
<title>icon_circleplus</title>
<g>
<path d="M50.66,4.76a30.71,30.71,0,1,0,30.7,30.7,30.71,30.71,0,0,0-30.7-30.7M66.55,38.87H54.06V51.35H47.25V38.87H34.76V32.06H47.25V19.57h6.81V32.06H66.55Z"></path>
</g>
</svg>
</div>
<div class="product-descriptions__title">Advantage Plus</div>
<div class="product-descriptions__description">More control, more options, more ways to waive the monthly fee.</div>
<a id="" class="product-descriptions__link" href="#" data-index="1">
See details
</a>
</div>
<div class="product-descriptions__item">
<div class="product-descriptions__icon-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 70" aria-hidden="true" focusable="false">
<title>icon_circleplus</title>
<g>
<path d="M50.66,4.76a30.71,30.71,0,1,0,30.7,30.7,30.71,30.71,0,0,0-30.7-30.7M66.55,38.87H54.06V51.35H47.25V38.87H34.76V32.06H47.25V19.57h6.81V32.06H66.55Z"></path>
</g>
</svg>
</div>
<div class="product-descriptions__title">Advantage Relationship</div>
<div class="product-descriptions__description">Everything you get with the Plus setting along with extra perks and services.</div>
<a id="" class="product-descriptions__link" href="#" data-index="2">
See details
</a>
</div>
</div>
您可以多次重新执行一条准备好的语句,并将不同的数组传递给每次执行。这与多查询代码一样好,并且更易于编码和阅读。
我从不使用多重查询(在一个SQL查询字符串中包含多个语句)。正确的做法很复杂,而且这样做没有任何好处。
绑定参数值时,一次必须在键上放置一个冒号前缀,以匹配参数占位符。但是他们修复了很久以前,以至于甚至修复了它们的PHP版本也已被弃用。您可以使用纯字符串作为绑定键。
您根本不需要使用$cols = implode(',', array_keys($order_item[0]));
function colon_prefix($param) { return ":$param"; }
$params = implode(',', array_map("colon_prefix", array_keys($order_item[0])));
$sql = "INSERT INTO orders_items ($cols) VALUES ($params)";
$stmt = $db->prepare($sql);
foreach ($order_item as $item) {
$stmt->execute($item);
}
,只需将数组传递给bindValue()
。
此外,上面的代码假定您的列名不需要分隔。也就是说,它们不是SQL保留字,并且不包含空格,标点符号或国际字符等特殊字符。
答案 1 :(得分:-1)
在获取索引元素总和后在for循环中打印。
$arr_count = count($array);
for($i = 0; $i <= $arr_count; $i++){
$insert_ord_query = $dbh->prepare("INSERT INTO orders(name, quantity, price, order_id) VALUES(:name, :quantity, :price, :order_id)");
$inser_ord_query->execute(array(
":name" => $array[$i]['name'],
":quantity" => $array[$i]['quantity'],
":price" => $array[$i]['price'],
":order_id" => $array[$i]['order_id']
));
}
echo "success";