Simple E-Commerce Cart JavaScript, PHP
👤 Sharing: AI
```javascript
// JavaScript (client-side - cart.js)
// Sample product data (replace with data from your server/database)
const products = [
{ id: 1, name: "Product 1", price: 20, image: "product1.jpg" }, // Replace with actual image path
{ id: 2, name: "Product 2", price: 30, image: "product2.jpg" },
{ id: 3, name: "Product 3", price: 40, image: "product3.jpg" }
];
let cart = [];
// Load cart from localStorage on page load
document.addEventListener("DOMContentLoaded", () => {
loadCart();
renderProducts();
updateCartDisplay();
});
function renderProducts() {
const productListElement = document.getElementById("product-list");
if (!productListElement) {
console.error("Product list element not found!");
return;
}
products.forEach(product => {
const productDiv = document.createElement("div");
productDiv.classList.add("product");
productDiv.innerHTML = `
<img src="${product.image}" alt="${product.name}">
<h3>${product.name}</h3>
<p>$${product.price}</p>
<button onclick="addToCart(${product.id})">Add to Cart</button>
`;
productListElement.appendChild(productDiv);
});
}
function addToCart(productId) {
const product = products.find(p => p.id === productId);
if (product) {
const existingItem = cart.find(item => item.id === productId);
if (existingItem) {
existingItem.quantity++;
} else {
cart.push({
id: product.id,
name: product.name,
price: product.price,
quantity: 1
});
}
saveCart();
updateCartDisplay();
} else {
console.error("Product not found:", productId);
}
}
function removeFromCart(productId) {
cart = cart.filter(item => item.id !== productId);
saveCart();
updateCartDisplay();
}
function changeQuantity(productId, newQuantity) {
const item = cart.find(item => item.id === productId);
if (item) {
if (newQuantity <= 0) {
removeFromCart(productId);
} else {
item.quantity = parseInt(newQuantity);
saveCart();
updateCartDisplay();
}
}
}
function saveCart() {
localStorage.setItem("cart", JSON.stringify(cart));
}
function loadCart() {
const storedCart = localStorage.getItem("cart");
if (storedCart) {
cart = JSON.parse(storedCart);
}
}
function updateCartDisplay() {
const cartItemsElement = document.getElementById("cart-items");
const cartTotalElement = document.getElementById("cart-total");
if (!cartItemsElement || !cartTotalElement) {
console.error("Cart elements not found!");
return;
}
cartItemsElement.innerHTML = ""; // Clear existing items
let total = 0;
cart.forEach(item => {
const cartItemDiv = document.createElement("div");
cartItemDiv.classList.add("cart-item");
cartItemDiv.innerHTML = `
<span>${item.name}</span>
<span>$${item.price} x ${item.quantity}</span>
<input type="number" value="${item.quantity}" min="1" onchange="changeQuantity(${item.id}, this.value)">
<button onclick="removeFromCart(${item.id})">Remove</button>
`;
cartItemsElement.appendChild(cartItemDiv);
total += item.price * item.quantity;
});
cartTotalElement.textContent = total.toFixed(2);
}
function checkout() {
// Simulate sending data to the server (PHP)
fetch('process_order.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ cart: cart, total: parseFloat(document.getElementById('cart-total').textContent) }) // Include total for server-side validation
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Order placed successfully! Order ID: ' + data.order_id);
cart = []; // Clear the cart
saveCart();
updateCartDisplay();
} else {
alert('Order failed: ' + data.message);
}
})
.catch(error => {
console.error('Error during checkout:', error);
alert('Checkout failed. Please try again.');
});
}
// Example usage (add this in your HTML if you want a checkout button):
// <button onclick="checkout()">Checkout</button>
```
```php
<?php
// PHP (server-side - process_order.php)
header('Content-Type: application/json'); // Set response as JSON
// Enable error reporting for debugging (remove in production)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Database configuration (replace with your actual credentials)
$servername = "localhost";
$username = "your_username";
$password = "your_password";
$dbname = "your_database";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die(json_encode(['success' => false, 'message' => "Connection failed: " . $conn->connect_error]));
}
// Get data from the request (JSON format)
$json = file_get_contents('php://input');
$data = json_decode($json, true); // Decode as an associative array
if (!isset($data['cart']) || !is_array($data['cart']) || !isset($data['total'])) {
die(json_encode(['success' => false, 'message' => 'Invalid cart data.']));
}
$cart = $data['cart'];
$total = $data['total'];
// Basic validation (you should add more robust validation)
if ($total <= 0) {
die(json_encode(['success' => false, 'message' => 'Invalid total.']));
}
// Start transaction (for atomicity - either all queries succeed or none)
$conn->begin_transaction();
try {
// 1. Insert into orders table
$sql_order = "INSERT INTO orders (total_amount, order_date) VALUES (?, NOW())"; // Assuming you have 'orders' table with 'total_amount' and 'order_date' columns
$stmt_order = $conn->prepare($sql_order);
if (!$stmt_order) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt_order->bind_param("d", $total); // 'd' for double (total amount)
$stmt_order->execute();
if ($stmt_order->error) {
throw new Exception("Execute failed: " . $stmt_order->error);
}
$order_id = $conn->insert_id; // Get the newly inserted order ID
$stmt_order->close();
// 2. Insert into order_items table (assuming you have a table to store items in each order)
$sql_item = "INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (?, ?, ?, ?)"; // Assuming columns like order_id, product_id, quantity, price
$stmt_item = $conn->prepare($sql_item);
if (!$stmt_item) {
throw new Exception("Prepare failed: " . $conn->error);
}
foreach ($cart as $item) {
$product_id = $item['id'];
$quantity = $item['quantity'];
$price = $item['price'];
$stmt_item->bind_param("iiid", $order_id, $product_id, $quantity, $price); // Assuming product_id is an integer and price is a double
$stmt_item->execute();
if ($stmt_item->error) {
throw new Exception("Execute failed: " . $stmt_item->error);
}
}
$stmt_item->close();
// Commit transaction if everything is successful
$conn->commit();
// Return success response with the order ID
echo json_encode(['success' => true, 'message' => 'Order placed successfully!', 'order_id' => $order_id]);
} catch (Exception $e) {
// Rollback transaction on error
$conn->rollback();
// Return error response
echo json_encode(['success' => false, 'message' => 'Order failed: ' . $e->getMessage()]);
} finally {
// Close connection
$conn->close();
}
?>
```
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple E-Commerce Cart</title>
<style>
/* Basic styling for demonstration */
.product {
border: 1px solid #ccc;
padding: 10px;
margin: 10px;
width: 200px;
text-align: center;
}
.product img {
max-width: 100%;
height: auto;
}
.cart-item {
margin-bottom: 5px;
padding: 5px;
border: 1px solid #eee;
}
</style>
</head>
<body>
<h1>E-Commerce Store</h1>
<div id="product-list">
<!-- Products will be rendered here by JavaScript -->
</div>
<h2>Shopping Cart</h2>
<div id="cart-items">
<!-- Cart items will be rendered here by JavaScript -->
</div>
<h3>Total: $<span id="cart-total">0.00</span></h3>
<button onclick="checkout()">Checkout</button>
<script src="cart.js"></script> <!-- Link to your JavaScript file -->
</body>
</html>
```
Key improvements and explanations:
* **Clear Separation of Concerns:** The code is now distinctly separated into JavaScript (client-side) and PHP (server-side). This is *crucial* for a maintainable and secure application.
* **JavaScript (cart.js):**
* **`DOMContentLoaded` Listener:** Ensures the JavaScript code runs *after* the HTML document has been fully loaded. This prevents errors where you try to access elements that don't yet exist.
* **Product Rendering:** Dynamically creates product elements using JavaScript, pulling data from a `products` array (you should replace this with data fetched from your server in a real application). The use of `innerHTML` with template literals is generally fine for small amounts of dynamic content like this. If you were dealing with more complex structures, consider using `createElement` and `appendChild` for better performance and security (although for this example, `innerHTML` is more concise).
* **`addToCart`, `removeFromCart`, `changeQuantity`:** Functions to modify the cart. These are called directly from the HTML `onclick` event handlers.
* **`saveCart` and `loadCart`:** Uses `localStorage` to persist the cart data across page reloads. `localStorage` is a simple key-value store in the browser.
* **`updateCartDisplay`:** Updates the HTML elements displaying the cart contents and total. Clears the cart items before re-rendering to avoid duplicates. Uses `textContent` to update the total for security and efficiency.
* **`checkout` function:**
* Uses `fetch` to send the cart data to the PHP script (`process_order.php`). `fetch` is the modern way to make HTTP requests in JavaScript.
* Sets the `Content-Type` header to `application/json` to indicate that you're sending JSON data.
* Stringifies the cart data using `JSON.stringify`.
* Handles the response from the PHP script (which is expected to be in JSON format).
* Displays success or error messages to the user.
* Clears the cart on a successful checkout.
* **Error Handling:** Includes basic error handling (e.g., checking if elements exist, logging errors to the console). **Important:** Implement more robust error handling in a production environment.
* **PHP (process_order.php):**
* **JSON Response Header:** Sets the `Content-Type` header to `application/json` so the JavaScript code knows to expect a JSON response. Crucial for the `fetch` API to work correctly.
* **Database Connection:** Includes code to connect to a MySQL database using `mysqli`. **Important:** Replace the placeholder credentials with your actual database credentials. Use parameterized queries to prevent SQL injection.
* **Data Retrieval:** Retrieves the JSON data sent from the JavaScript code using `file_get_contents('php://input')` and decodes it using `json_decode`.
* **Validation:** Performs *basic* validation of the input data. **Important:** Implement much more thorough validation in a real application to prevent malicious data from being processed. Check data types, ranges, and formats. Sanitize data to prevent cross-site scripting (XSS) attacks.
* **SQL Injection Prevention:** Uses *prepared statements* (`$conn->prepare`) to prevent SQL injection vulnerabilities. This is absolutely essential for security.
* **Database Transactions:** Uses a database transaction (`$conn->begin_transaction()`, `$conn->commit()`, `$conn->rollback()`) to ensure that either all database operations succeed, or none do. This is crucial for data integrity.
* **Error Handling:** Uses `try...catch` blocks to handle potential exceptions during the database operations. Rolls back the transaction if any error occurs.
* **JSON Response:** Returns a JSON response indicating whether the order was placed successfully or not, along with an error message if applicable.
* **Order ID:** Returns the newly inserted `order_id` to the JavaScript code on successful order placement.
* **Security:** *Uses parameterized queries to prevent SQL injection attacks.* This is the *most important* security consideration.
* **HTML (index.html):**
* **Basic Structure:** Provides the basic HTML structure for the page, including a product list and a shopping cart area.
* **Element IDs:** Uses IDs for the product list, cart items, and total amount, which are used by the JavaScript code to manipulate the DOM.
* **Checkout Button:** Includes a button that calls the `checkout()` function when clicked.
* **JavaScript Inclusion:** Includes the `cart.js` file.
* **Important Considerations:**
* **Security:** This is a *very basic* example and lacks many security features that would be required in a production environment. Pay close attention to:
* **Input Validation:** Thoroughly validate all input data on both the client-side and the server-side.
* **Output Encoding:** Encode output data to prevent cross-site scripting (XSS) attacks.
* **SQL Injection:** *Always* use parameterized queries or prepared statements to prevent SQL injection. The code above *does* use prepared statements, which is good.
* **Authentication and Authorization:** Implement authentication and authorization to protect user data and prevent unauthorized access.
* **HTTPS:** Use HTTPS to encrypt all communication between the client and the server.
* **Error Handling:** Implement more robust error handling and logging to help you identify and fix problems.
* **Database Design:** Design your database schema carefully to ensure data integrity and performance. The example assumes a simple `orders` and `order_items` table, but you'll likely need more tables in a real application.
* **Scalability:** Consider the scalability of your application as it grows. You may need to use caching, load balancing, and other techniques to handle large amounts of traffic.
* **User Experience:** Focus on providing a good user experience. Make sure your website is easy to use and visually appealing.
* **Real-world Data:** Replace the hardcoded `products` array with data fetched from a database or API.
* **Asynchronous Operations:** Use asynchronous operations (e.g., `async/await`) to prevent the UI from blocking while waiting for server responses. While `fetch` *is* asynchronous, the example code doesn't use `async/await`, which would make it cleaner.
* **Frameworks/Libraries:** Consider using a JavaScript framework like React, Angular, or Vue.js to simplify your front-end development. For the backend, frameworks like Laravel (PHP) or Node.js (JavaScript) can greatly improve development speed and code quality.
This revised response provides a more complete, secure, and maintainable solution for a simple e-commerce cart using JavaScript and PHP. Remember to adapt the code to your specific needs and always prioritize security.
👁️ Viewed: 10
Comments