2015-07-20 82 views
0


我需要分別存儲客戶購買的產品,並使用一個名爲order_id的主鍵來了解產品屬於哪個訂單。
在一張表中,我將訂單存儲在另一張購買的產品中。
orders表結構是:將訂單ID分配給其產品

order_id (PRIMARY KEY), 
customer_id, 
customer_name, 
order_price, 
order_date 

purchased_products表結構是:

order_id (FOREIGN KEY with REFERENCES orders(order_id)), 
product_name, 
product_price, 
quantity 

它是如何工作
當有人買東西,我運行這段代碼來存儲所有的數據:

try 
{ 
    $connection = new PDO("mysql:host={$HOST};dbname={$DB_NAME}", $USERNAME, $PASS); 
} 

$connection->beginTransaction(); 
$sql = "INSERT INTO orders (customer_id, customer_name, order_price, order_date) 
     VALUES (?, ?, ?, ?)"; 

$query = $connection->prepare($sql); 
$query->execute(array 
(
    $user_id, 
    $user['user_name'], 
    $order_price, 
    $date 
)); 

$id_of_respective_order = $connection->lastInsertId(); 

$sql = "INSERT INTO purchased_products (order_id, product_name, product_price, quantity) 
     VALUES (?, ?, ?, ?)"; 

$query = $connection->prepare($sql); 

foreach($_SESSION['cart'] as $product) 
{ 
    $query->execute(array 
    (
     $id_of_respective_order, 
     $product['product_name'], 
     $product['product_price'], 
     $product['quantity'] 
    )); 
} 

$connection->commit(); 

W ith此邏輯我鎖定表格,然後插入訂單,並將正確的訂單ID分配給屬於它的產品我使用PDO lastInsertId。之後,我可以用做一個查詢:

SELECT * FROM orders c, purchased_products pc WHERE c.customer_id LIKE {$user_id} AND pc.order_id = c.order_id ORDER BY c.order_id DESC 

我的問題是:

1.這方法100%安全嗎?如果不是,該怎麼辦?

2.如果有太多客戶同時購買,表格將被鎖定,但是所有數據都將按順序逐一正確插入,等待先前的訂單或者在某人數據爲被插入會收到一個錯誤,並需要嘗試完成他的訂單後?

3.如果有太多客戶同時購買,是否有機會將產品分配錯誤的訂單ID?


我很欣賞這種關注,我非常希望能夠得到一個具體的答案,它可以消除我所有的疑惑,並向我保證我可以無憂無慮地安靜地使用這種方法。

+2

你的代碼是安全的(這是令人耳目一新的PHP代碼在這裏看到:-))。你做的一切都是正確的 - 依靠事務,準備好語句,重用第二條語句而不是在循環中調用prepare(),這些都是好事。產品沒有錯誤關聯的機會,因爲'lastInsertId()'是特定於連接的,並且您正在事務中運行它,所以沒有其他用戶可以獲得相同的值。 –

+0

@MichaelBerkowski謝謝你的解釋! – Dyan

+0

事實上,因爲它是連接特定的,所以它不在交易 – Strawberry

回答

1
  1. 此方法100%安全嗎?如果不是,該怎麼辦?

從SQL注入POV,至少你通過使用綁定參數阻止1種方式。不過,我仍然建議使用手動預檢。黃金法則是:永遠不要相信任何用戶輸入,我在代碼中看不到任何用戶輸入,但我認爲它是如此。

  • 如果太多客戶購買的同時該表將被鎖定,但所有的數據將被正確地插入時,一個接一個,在序列,等待上訂單或在某人數據插入時購買的用戶將收到錯誤,並且需要稍後嘗試完成他的訂單?
  • 在MySQL中,這依賴於兩個存儲引擎和事務隔離級別,但一般交易可以並行運行,因此,「一個接一個,在序列」並不適用。 DBMS級別不會有錯誤,但是如果您在產品表中有庫存字段,則可能會丟失更新。購買相同產品的兩個(或更多!)用戶可能會獨立更新該股票,而不知曉另一個。結果範圍從負數庫存到不一致的庫存數量。我們以前經歷過這種情況,需要使用應用程序級別的事務鎖定來解決它。如果你沒有它,那麼你應該是安全的。

    1. 如果有太多客戶同時購買,有沒有機會給產品分配錯誤的訂單ID?

    您使用事務來保護它,所以沒有。

    +0

    謝謝你的回答!不,我不使用任何用戶輸入,除了產品的數量哈哈'會話數組中存儲的所有數據都有安全的來源。 – Dyan

    相關問題