php - 使用 PHP 添加到 MySQL 会添加两次并出现外部 ID 约束问题

标签 php mysql

出于某种原因,当我添加到我的数据库时,这一行 $query = "INSERT INTO customers (id, name, address) VALUES (NULL,'$name', '$address')"; 添加客户两次。所以一个客户将同时拥有 id 1 和 id 2。随后获取 $last_id 将始终获得第二个 id 号,因此对于输入 id 1 和 2 的客户,$last_id == 2。我通过删除第一个副本来消除这个问题,但是我如何首先防止它发生呢?我正在使用 Chrome,但它也发生在 safari 中。

<?php 
// Include the ShoppingCart class.  Since the session contains a
// ShoppingCard object, this must be done before session_start().
require "../application/cart.php";
session_start(); 
?>

<!DOCTYPE html>

<?php 

$orderErr = $nameErr = $addressErr = "";
$name = $address = "";

// If this session is just beginning, store an empty ShoppingCart in it.
if (!isset($_SESSION['cart'])) {
    $_SESSION['cart'] = new ShoppingCart();
}

if (($_SESSION['cart']->count_order()) == 0) {
    $orderErr = "There is nothing in the order, cannot checkout";

}

// sanitizing function
function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}


if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (empty($_POST["name"])) {
        $nameErr = "Name is required";
    }
    else {
        $name = test_input($_POST["name"]);
    }

    if (empty($_POST["address"])) {
        $addressErr = "Address is required";
    } 
    else {
        $address = test_input($_POST["address"]);
   }

    //if there is an order, and name and address exist after sanaitizing,
    // add to db
    if ($name != "" && $address != "" && ($_SESSION['cart']->count_order()) != 0) {
        require_once 'login.php';
        $conn = new mysqli($hn, $un, $pw, $db);
        if ($conn->connect_error) die($conn->connect_error);

        //adding current customer
        $query = "INSERT INTO customers (id, name, address) VALUES (NULL, '$name', '$address')";
        echo "ok<br>";

        $result = $conn->query($query);
        if ($conn->query($query) === TRUE) {
            echo "New record created successfully" . "<br>";
            $last_id = $conn->insert_id;
            echo $last_id . "<br>";
        } else {
            echo "Error: " . $sql . "<br>" . $conn->error;
        }
        $delete_id = $last_id - 1;

        // deleting duplicate
        $query = "DELETE FROM customers WHERE id = '$delete_id'";
        if ($conn->query($query) === TRUE) {
            echo "duplicate deleted successfully" . "<br>";
        } else {
            echo "Error: " . $sql . "<br>" . $conn->error;
        }

        //send orders to db
        $_SESSION['cart']->send_order_to_db($last_id, $conn);

        $conn->close();

        session_unset();  // remove all session variables
        session_destroy();


    }
}

?>

<html lang="en">

<head>
<title>Checkout</title>
<style>
.error {color: #FF0000;}
</style>
</head>

<body>

<h2>Checkout</h2>

<p>Here is your order: <?php
// Poor man's display of shopping cart
if (!isset($_SESSION['cart'])) {
    $_SESSION['cart'] = new ShoppingCart();
}
$_SESSION['cart']->table();
?></p>
<span class="error"><?php echo $orderErr;?></span>

<h3> Checkout Form: </h3>
<p><span class="error">* required field.</span></p>
<form method = "post" >
    Name: <input type="text" name="name" value="<?php echo $name;?>">
    <span class="error">* <?php echo $nameErr;?></span>
    <br><br>
    Address: <input type="text" name="address" value="<?php echo $address;?>">
    <span class="error">* <?php echo $nameErr;?></span>
    <br><br>
    <input type="submit" name="submit" value="Submit"> 
</form>

<p>Your credit card will be billed.  Thanks for the order!</p>

<p><a href="index4.php">Shop some more!</a></p>

</body>
</html>

第二个问题是函数SOLVE。请参阅下面的编辑

public function send_order_to_db($last_id, $conn) {
      foreach ($this->order  as $variety => $quantity)
        $query = "INSERT INTO orders (id, variety, quantity) VALUES" .
          "('$last_id', '$variety', '$quantity')";

        echo 'added ' . $quantity . ' ' . $variety;

        $result = $conn->query($query);
        if (!$result) echo "INSERT failed: $query<br>" .
          $conn->error . "<br><br>";
    }

我在输入客户信息后调用它,只添加数组 $this->order 中的最后一个元素。是因为 foreach 不像循环那样工作吗?那么我会使用 for 循环吗?还是跟数据库有关系?

编辑 我意识到我在 foreach 语句周围没有括号。现在我这样做了,它有效。添加所有具有相同 ID 的订单。

这是我的数据库:

/* To start with a fresh new database named store, we will delete one
 * if one already exists:
 */
DROP DATABASE IF EXISTS store;

CREATE DATABASE store;


GRANT ALL PRIVILEGES ON store.* to user@localhost IDENTIFIED BY 'name';

USE store;

CREATE TABLE IF NOT EXISTS customers (
 id int NOT NULL AUTO_INCREMENT,
 name text NOT NULL,
 address text NOT NULL,
 PRIMARY KEY (id)
) ENGINE=InnoDB; 

CREATE TABLE IF NOT EXISTS orders (
 id int NOT NULL,
 variety varchar(20) NOT NULL,
 quantity int(11) NOT NULL,
 PRIMARY KEY (id, variety),
 FOREIGN KEY (id)
 REFERENCES customers(id)
 ON DELETE CASCADE
 ON UPDATE CASCADE
) ENGINE=InnoDB; 

最佳答案

问题1

您的第一个问题是记录被插入两次是因为您运行了两次查询:

$result = $conn->query($query);
if ($conn->query($query) === TRUE) {

您应该使用 $result 内容来检查它是否有效,而不是重新运行查询:

$result = $conn->query($query);
if ($result === true) {

问题2

记录只插入最后一条记录 - 这是因为你没有为你的 foreach 循环使用大括号,所以它只在循环中的控制结构之后运行第一行 - 其余的将仅在循环完成后执行。查看注释流程:

public function send_order_to_db($last_id, $conn) {
    foreach ($this->order  as $variety => $quantity)
        // This line is run in the loop
        $query = "INSERT INTO orders (id, variety, quantity) VALUES" .
                 "('$last_id', '$variety', '$quantity')";
        // This line is only run once, after the foreach has finished
        echo 'added ' . $quantity . ' ' . $variety;
        $result = $conn->query($query);
        if (!$result)
            echo "INSERT failed: $query<br>" .
                 $conn->error . "<br><br>";
}

你只需要将内容用大括号括起来:

public function send_order_to_db($last_id, $conn) {
    foreach ($this->order  as $variety => $quantity) {
        // This line is run in the loop
        $query = "INSERT INTO orders (id, variety, quantity) VALUES" .
                 "('$last_id', '$variety', '$quantity')";
        // So is all below now
        echo 'added ' . $quantity . ' ' . $variety;
        $result = $conn->query($query);
        if (!$result) {
            echo "INSERT failed: $query<br>" .
                 $conn->error . "<br><br>";
        }
    }
}

请注意,末尾 if 之后的大括号不是必需的,但最好始终使用大括号以提高可读性(并帮助您发现此类错误)。

关于php - 使用 PHP 添加到 MySQL 会添加两次并出现外部 ID 约束问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29276535/

相关文章:

php - 将键附加到现有数组值

mysql - 当中间有另一个表未使用时,如何连接两个表?

diff - 使用 mysqldump 比较两个数据库?

php - mysql 查询以获取匹配的记录

php - MySQL 查询表 - 不显示第一个结果

php - pcntl 在 Ubuntu 'for security reasons' 上不起作用

php - 在 IIS 重新启动之前,使用 PHP exec headless 运行 Google Chrome 不会返回输出

php - 返回页面后继续运行 php 脚本

php - 使用 mysql_fetch_object 时出现奇怪的 MySQL 错误 "Empty row packet body"(PHP 5.3.3)

mysql - 按最常见到最不常见的顺序对列进行排序,忽略重复项