php实现交易
PHP 实现交易系统
数据库设计
交易系统需要设计数据库表来存储交易信息。常见的表包括用户表、商品表、订单表和交易记录表。用户表存储用户信息,商品表存储商品信息,订单表记录用户下单信息,交易记录表保存交易详情。
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
balance DECIMAL(10, 2) DEFAULT 0.00
);
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
stock INT NOT NULL
);
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
total_price DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE transactions (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
用户下单逻辑
用户下单时需要检查商品库存和用户余额,确保交易可以完成。使用事务(Transaction)保证数据一致性。

function placeOrder($userId, $productId, $quantity) {
$db = new PDO('mysql:host=localhost;dbname=shop', 'username', 'password');
$db->beginTransaction();
try {
// 检查商品库存
$stmt = $db->prepare("SELECT price, stock FROM products WHERE id = ? FOR UPDATE");
$stmt->execute([$productId]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if ($product['stock'] < $quantity) {
throw new Exception("Insufficient stock");
}
$totalPrice = $product['price'] * $quantity;
// 检查用户余额
$stmt = $db->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE");
$stmt->execute([$userId]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user['balance'] < $totalPrice) {
throw new Exception("Insufficient balance");
}
// 扣减库存
$stmt = $db->prepare("UPDATE products SET stock = stock - ? WHERE id = ?");
$stmt->execute([$quantity, $productId]);
// 扣减余额
$stmt = $db->prepare("UPDATE users SET balance = balance - ? WHERE id = ?");
$stmt->execute([$totalPrice, $userId]);
// 创建订单
$stmt = $db->prepare("INSERT INTO orders (user_id, product_id, quantity, total_price) VALUES (?, ?, ?, ?)");
$stmt->execute([$userId, $productId, $quantity, $totalPrice]);
$orderId = $db->lastInsertId();
// 记录交易
$stmt = $db->prepare("INSERT INTO transactions (order_id, amount) VALUES (?, ?)");
$stmt->execute([$orderId, $totalPrice]);
$db->commit();
return ["success" => true, "order_id" => $orderId];
} catch (Exception $e) {
$db->rollBack();
return ["success" => false, "message" => $e->getMessage()];
}
}
支付处理
支付处理通常需要与第三方支付网关集成。以下是一个简单的支付处理示例,模拟与支付网关的交互。
function processPayment($transactionId, $amount) {
// 模拟支付网关API调用
$paymentGatewayResponse = callPaymentGateway($amount);
if ($paymentGatewayResponse['success']) {
$db = new PDO('mysql:host=localhost;dbname=shop', 'username', 'password');
$stmt = $db->prepare("UPDATE transactions SET status = 'completed' WHERE id = ?");
$stmt->execute([$transactionId]);
$stmt = $db->prepare("UPDATE orders SET status = 'completed' WHERE id = (SELECT order_id FROM transactions WHERE id = ?)");
$stmt->execute([$transactionId]);
return ["success" => true, "message" => "Payment processed successfully"];
} else {
return ["success" => false, "message" => "Payment failed"];
}
}
function callPaymentGateway($amount) {
// 实际项目中这里会调用真实的支付网关API
// 模拟成功支付
return ["success" => true, "transaction_id" => uniqid()];
}
交易查询
提供交易查询功能,允许用户和管理员查看交易记录。

function getTransactionHistory($userId) {
$db = new PDO('mysql:host=localhost;dbname=shop', 'username', 'password');
$stmt = $db->prepare("
SELECT t.id, t.amount, t.status, t.created_at, o.id as order_id, p.name as product_name
FROM transactions t
JOIN orders o ON t.order_id = o.id
JOIN products p ON o.product_id = p.id
WHERE o.user_id = ?
ORDER BY t.created_at DESC
");
$stmt->execute([$userId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
安全性考虑
交易系统需要特别注意安全性,包括防止SQL注入、XSS攻击和CSRF攻击。使用预处理语句防止SQL注入,对输出进行转义防止XSS,使用CSRF令牌防止跨站请求伪造。
// 示例:CSRF防护
session_start();
function generateCsrfToken() {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
function validateCsrfToken($token) {
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
性能优化
对于高并发的交易系统,需要考虑数据库索引优化、缓存和队列处理。为常用查询字段添加索引,使用Redis缓存热门商品信息,使用消息队列处理支付通知等异步任务。
-- 添加索引示例
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_transactions_order_id ON transactions(order_id);






