php转账实现
PHP 转账功能实现
实现 PHP 转账功能通常涉及数据库操作、事务处理和安全性验证。以下是关键步骤和代码示例:
数据库表设计
创建 accounts 表和 transactions 表存储账户和交易记录:
CREATE TABLE accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
balance DECIMAL(10, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD'
);
CREATE TABLE transactions (
id INT AUTO_INCREMENT PRIMARY KEY,
from_account INT NOT NULL,
to_account INT NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
fee DECIMAL(10, 2) DEFAULT 0,
status ENUM('pending', 'completed', 'failed') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
转账核心逻辑
使用 PDO 实现带有事务的转账操作:
function transferMoney($fromAccountId, $toAccountId, $amount) {
$db = new PDO('mysql:host=localhost;dbname=your_db', 'username', 'password');
$db->beginTransaction();
try {
// 检查账户是否存在
$stmt = $db->prepare("SELECT balance FROM accounts WHERE id = ? FOR UPDATE");
$stmt->execute([$fromAccountId]);
$fromBalance = $stmt->fetchColumn();
if ($fromBalance === false) {
throw new Exception("转出账户不存在");
}
// 检查余额是否充足
if ($fromBalance < $amount) {
throw new Exception("余额不足");
}
// 扣减转出账户
$db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?")
->execute([$amount, $fromAccountId]);
// 增加转入账户
$db->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?")
->execute([$amount, $toAccountId]);
// 记录交易
$db->prepare("INSERT INTO transactions (from_account, to_account, amount) VALUES (?, ?, ?)")
->execute([$fromAccountId, $toAccountId, $amount]);
$db->commit();
return true;
} catch (Exception $e) {
$db->rollBack();
error_log("转账失败: " . $e->getMessage());
return false;
}
}
安全增强措施
-
输入验证:
if (!is_numeric($amount) || $amount <= 0) { die("金额必须为正数"); } -
防止并发问题:
- 使用
SELECT ... FOR UPDATE锁定账户记录 - 设置数据库隔离级别为
READ COMMITTED
- API 防护:
// 验证CSRF令牌 if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { die("非法请求"); }
扩展功能建议
-
手续费计算:
$fee = $amount * 0.01; // 1%手续费 $netAmount = $amount - $fee; -
交易状态通知:
if (transferMoney($from, $to, $amount)) { sendEmailNotification($to, "收到转账 $amount"); } -
交易记录查询:
function getTransactionHistory($accountId) { $stmt = $db->prepare("SELECT * FROM transactions WHERE from_account = ? OR to_account = ? ORDER BY created_at DESC"); $stmt->execute([$accountId, $accountId]); return $stmt->fetchAll(); }
性能优化
-
为频繁查询的字段添加索引:
CREATE INDEX idx_account_user ON accounts(user_id); CREATE INDEX idx_transaction_account ON transactions(from_account, to_account); -
批量处理优化: 对于批量转账,考虑使用批量插入和更新语句减少数据库往返次数。
以上实现包含了转账功能的核心要素,实际应用中还需根据具体业务需求进行扩展和完善。特别注意要处理好事务的原子性和错误恢复机制。







