*结帐无法正常运行 HELP!!!* - 没有数据库的 PHP 购物车 [关闭]

问题描述 投票:0回答:0

我不确定是否正确我认为错误是因为我期待来自 AJAX 请求的 JSON 响应,但是我收到的 HTML 响应不是正确的 JSON 格式。

error message from console

1-products.php(这里有所有产品的详细信息)

<?php
$products = [
  1  => ["name" => "Apple", "price" => 5.50, "image" => "book.png"],
  2  => ["name" => "Mango", "price" => 15.00, "image" => "bag.png"],
  3  => ["name" => "Orange", "price" => 18.55, "image" => "cloth.png"],
  4  => ["name" => "Pear", "price" => 15.75, "image" => "pants.png"]
];

2-ajax-cart.php(所有功能包括结帐)

<?php
if (isset($_POST["req"])) {
  // (A) INIT SHOPPING CART
  session_start();
  if (!isset($_SESSION["cartI"])) {
    $_SESSION["cartI"] = []; // cart items
    $_SESSION["cartC"] = 0;  // total quantity
  }

  // (B) UPDATE CART COUNT
  function ccount () {
    $_SESSION["cartC"] = 0;
    if (count($_SESSION["cartI"])!=0) {
      foreach ($_SESSION["cartI"] as $id=>$qty) { $_SESSION["cartC"] += $qty; }
    }
  }

  // (C) STANDARD SYSTEM RESPONSE
  function respond ($status=1, $msg="OK") {
    echo json_encode(["status"=>$status, "msg"=>$msg, "count" => $_SESSION["cartC"]]);
  }

  // (D) CART ACTIONS
  switch ($_POST["req"]) {
    // (D1) GET COUNT
    case "count": respond(); break;

    // (D2) ADD / CHANGE QUANTITY / REMOVE
    // send id only to add item
    // send id and qty to set quantity
    // send id and 0 qty to remove item
    case "set":
      $max = 99; // max allowed quantity per item
      $item = &$_SESSION["cartI"][$_POST["id"]];
      if (isset($_POST["qty"])) { $item = $_POST["qty"]; }
      else { if (isset($item)) { $item++; } else { $item = 1; } }
      if ($item<=0) { unset($_SESSION["cartI"][$_POST["id"]]); }
      if ($item > $max) { $item = $max; }
      ccount(); respond(); break;

    // (D3) NUKE
    case "nuke":
      $_SESSION["cartI"] = [];
      $_SESSION["cartC"] = 0;
      respond(); break;

    // (D4) GET ALL ITEMS IN CART
    case "get":
      // (D4-1) CART IS EMPTY
      if ($_SESSION["cartC"]==0) { respond(1, null); break; }

      // (D4-2) GET PRODUCTS + FILTER ILLEGAL
      require "1-products.php";
      $items = [];
      foreach ($_SESSION["cartI"] as $id=>$qty) {
        if (isset($products[$id])) {
          $items[$id] = $products[$id];
          $items[$id]["qty"] = $qty;
        } else {
          $_SESSION["cartC"] -= $_SESSION["cartI"][$id];
          unset($_SESSION["cartI"][$id]);
        }
      }
      if ($_SESSION["cartC"]==0) { respond(1, null); break; }
      respond(1, $items); break;

    // (D5) CHECKOUT
    case "checkout":
      // (D5-1) CART IS EMPTY
      if ($_SESSION["cartC"]==0) { respond(0, "Cart Empty"); break; }

      // (D5-2) EMAIL TO ADMIN
      require "1-products.php";
      $to = "[email protected]";
      $subject = "Order Received";
      $body = "Name: " . $_POST["name"] . "\r\n";
      $body .= "Email: " . $_POST["email"] . "\r\n";
      foreach ($_SESSION["cartI"] as $id=>$qty) {
        $body .= sprintf("%s X %s\r\n", $qty, $products[$id]["name"]);
      }
      if (mail($to, $subject, $body)) {
        $_SESSION["cartI"] = [];
        $_SESSION["cartC"] = 0;
        respond();
      } else { respond(0, "ERROR SENDING MAIL"); }
      break;
  }
}

3a-shop.css(主页的CSS代码)

/* (A) WHOLE PAGE */
* {
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}
body {
  padding: 0;
  max-width: 1000px;
  margin: 0 auto;
  background: #ebebeb;
}
.button {
  padding: 10px;
  border: 0;
  font-weight: 700;
  color: #fff;
  background: #b90909;
  cursor: pointer;
}

/* (B) PRODUCTS + CART */
/* (B1) WRAPPER */
#wrap { position: relative; }

/* (B2) HEADER */
#head {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  padding: 20px 10px;
  font-size: 16px;
  color: #fff;
  background: #282828;
}
#iDummy, #iCart {
  margin: 0 10px;
  cursor: pointer;
}
#cCart {
  font-weight: 700;
  padding: 5px;
  margin-left: 5px;
  background: #951818;
}

/* (B3) PRODUCTS WRAPPER */
#products {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px; padding: 20px;
}
@media screen and (max-width:600px) {
  #products { grid-template-columns: repeat(2, 1fr); }
}

/* (B4) PRODUCTS */
.pCell {
  padding: 10px;
  background: #fff;
}
.pImg {
  width: 100%;
  height: 150px;
  padding: 10px 20px;
  object-fit: contain;
}
.pName, .pPrice { margin: 5px 0; }
.pName { font-size: 1.3rem; }
.pPrice { font-size: 0.9rem; color: #686868; }
.pAdd { width: 100%; }

/* (B5) CART WRAPPER */
#wCart {
  display: none;
  position: absolute;
  top: 0; left: 0; z-index: 999;
  width: 320px; padding: 15px;
  height: 100%; min-height: 100vh;
  background: #f5f5f5;
  border-right: 1px solid #a7a7a7;
  border-left: 1px solid #a7a7a7;
}
#wCart.show { display: block; }
#wCartClose {
  font-size: 20px;
  background: #282828;
}

/* (B6) CART ITEMS */
.cCell {
  display: flex;
  align-items: stretch;
  margin-bottom: 15px;
  border: 1px solid #e3e3e3;
  background: #fff;
}
.cCell.empty { padding: 10px; }
.cQty {
  text-align: center;
  width: 50px;
  border: 0;
  background: #e7e7e7;
}
.cInfo {
  flex-grow: 1;
  padding: 10px 5px;
}
.cName { font-weight: 700; }
.cPrice { font-size: 0.9rem; }

/* (C) CHECKOUT */
#checkout {
  position: fixed;
  top: 0; left: 0; z-index: 999;
  width: 100vw; height: 100vh;
  background: rgba(0, 0, 0, 0.8);
  display: none;
  align-items: center;
  justify-content: center;
}
#checkout.show { display: flex; }
#checkout form {
  position: relative;
  width: 400px;
  padding: 20px;
  background: #fff;
}
#checkout label, #checkout input {
  display: block;
  width: 100%;
}
#checkout label { padding: 10px 0; }
#checkout input { padding: 10px; }
#checkout input[type=submit] { margin-top: 20px; }
#coClose {
  position: absolute;
  top: 0; right: 0;
}


3a-shop.php(主页在这里)

<!DOCTYPE html>
<html>
  <head>
    <title>Shopping Page Demo</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="3a-shop.css">
    <script src="3b-cart.js"></script>
  </head>
  <body>
    <!-- (A) PRODUCTS + SHOPPING CART -->
    <div id="wrap">
      <!-- (A1) HEADER -->
      <div id="head">
        <div id="iCart" onclick="cart.show()">
          My Cart <span id="cCart">0</span>
        </div>
      </div>

      <!-- (A2) PRODUCTS -->
      <div id="products"><?php
        require "1-products.php";
        foreach ($products as $i=>$p) { ?>
        <div class="pCell">
          <img class="pImg" src="images/<?=$p["image"]?>">
          <div class="pName"><?=$p["name"]?></div>
          <div class="pPrice">$<?=$p["price"]?></div>
          <input class="pAdd button" type="button" value="Add To Cart" onclick="cart.add(<?=$i?>)">
        </div>
        <?php } ?>
      </div>

      <!-- (A3) CART ITEMS -->
      <div id="wCart">
        <span id="wCartClose" class="button" onclick="cart.toggle(cart.hWCart, false)">&#8678;</span>
        <h2>SHOPPING CART</h2>
        <div id="cart"></div>
      </div>
    </div>

    <!-- (B) CHECKOUT FORM -->
    <div id="checkout"><form onsubmit="return cart.checkout()">
      <div id="coClose" class="button" onclick="cart.toggle(cart.hCO, false)">X</div>
      <label>Name</label>
      <input type="text" id="coName" required value="Testing">
      <label>Email</label>
      <input type="email" id="coEmail" required value="[email protected]">
      <input class="button" type="submit" value="Checkout">
    </form></div>
  </body>
</html>

3b-cart.js(用于购物车的 JavaScript)

var cart = {
  // (A) HELPER - AJAX FETCH
  ajax : (data, after) => {
    // (A1) FORM DATA
    let form = new FormData();
    for (let [k, v] of Object.entries(data)) { form.append(k, v); }

    // (A2) FETCH
    fetch("2-ajax-cart.php", { method:"POST", body:form })
    .then(res => res.json())
    .then(res => {
      if (res.status==1) { after(res); }
      else { alert(res.msg); }
    })
    .catch(err => console.error(err));
  },

  // (B) HELPER - TOGGLE HTML SECTIONS
  toggle : (target, show) => {
    if (show) { target.className = "show"; }
    else { target.className = ""; }
  },

  // (C) INITIALIZE
  hCart : null, // html cart
  hWCart : null, // html cart wrapper
  hCCart : null, // html cart count
  hCO : null, // html checkout wrapper
  init : () => {
    // (C1) GET HTML ELEMENTS
    cart.hCart = document.getElementById("cart");
    cart.hWCart = document.getElementById("wCart");
    cart.hCCart = document.getElementById("cCart");
    cart.hCO = document.getElementById("checkout");

    // (C2) UPDATE CART COUNT
    cart.ajax({ req : "count" }, res => cart.count(res.count));
  },

  // (D) UPDATE CART COUNT
  count : qty => {
    cart.hCCart.innerHTML = qty;
    if (cart.hWCart.classList.contains("show")) { cart.show(); }
  },

  // (E) SHOW CART ITEMS
  show : () => {
    // (E1) RESET
    cart.toggle(cart.hWCart, true);
    cart.hCart.innerHTML = "";

    // (E2) LOAD & GENERATE HTML
    cart.ajax({ req : "get" }, items => {
      // (E2-1) ITEMS IN CART
      items = items.msg;

      // (E2-2) CART IS EMPTY
      if (items==null) {
        cart.hCart.innerHTML = `<div class="cCell empty">Cart is empty</div>`;
      }

      // (E2-3) DRAW CART ITEMS
      else {
        let row, subtotal, total = 0;
        for (let [id, item] of Object.entries(items)) {
          // CALCULATE SUBTOTAL
          subtotal = item["price"] * item["qty"];
          total += subtotal;

          // ITEM ROW
          row = document.createElement("div");
          row.className = "cCell";
          row.innerHTML = `<input class="cQty" type="number" value="${item["qty"]}" 
          min="0" max="99" onchange="cart.change(${id}, this.value)">
          <div class="cInfo">
            <div class="cName">${item["name"]}</div>
            <div class="cPrice">$${subtotal.toFixed(2)}</div>
          </div>
          <input class="cDel button" type="button" value="X" onclick="cart.remove(${id})">`;
          cart.hCart.appendChild(row);
        }

        // CART TOTALS
        row = document.createElement("div");
        row.className = "cCell";
        row.innerHTML = `<input class="cDel button" type="button" value="X" onclick="cart.empty()">
        <div class="cInfo">
          <div class="cName">Total</div>
          <div class="cPrice">$${total.toFixed(2)}</div>
        </div>
        <input class="cDel button" type="button" value="&gt;" onclick="cart.toggle(cart.hCO, true)">`;
        cart.hCart.appendChild(row);
      }
    });
  },

  // (F) ADD ITEM TO CART
  add : id => cart.ajax(
    { req : "set", id : id },
    res => cart.count(res.count)
  ),

  // (G) CHANGE ITEM QTY
  change : (id, qty) => cart.ajax(
    { req : "set", id : id, qty : qty },
    res => cart.count(res.count)
  ),

  // (H) REMOVE ITEM
  remove : id => cart.ajax(
    { req : "set", id : id, qty : 0 },
    res => cart.count(res.count)
  ),

  // (I) NUKE
  empty : () => { if (confirm("Reset cart?")) {
    cart.ajax(
      { req : "nuke" },
      res => cart.count(res.count)
    ); 
  }},

  // (J) CHECKOUT
  checkout : () => {
    cart.ajax({
      req : "checkout",
      name : document.getElementById("coName").value,
      email : document.getElementById("coEmail").value
    }, res => location.href = "3c-thank-you.html"); 
    return false;
  }
};
window.onload = cart.init;

3c-thank-you.html(感谢客户的简单页面)

<!DOCTYPE html>
<html>
  <head>
    <title>Done</title>
    <meta charset="utf-8">
  </head>
  <body>
    <h1>Thank You</h1>
    <p>Order received.</p>
  </body>
</html>

我不知道该怎么做请帮忙~~

javascript php ajax
© www.soinside.com 2019 - 2024. All rights reserved.