<?php
// 配置常量
define('ORDER_FILE', "$document_root/web/orders/orders.txt");
function writeOrderToFile(string $outputstring): void {
try {
// 原子性操作:打开+加锁一步完成(PHP 7.4+特性)
$fp = fopen(ORDER_FILE, 'ab');
if (!$fp) {
throw new RuntimeException("无法打开订单文件");
}
if (!flock($fp, LOCK_EX | LOCK_NB)) {
fclose($fp);
throw new RuntimeException("文件正被其他进程占用");
}
// 二进制安全写入
$bytes = fwrite($fp, $outputstring);
if ($bytes === false) {
flock($fp, LOCK_UN);
fclose($fp);
throw new RuntimeException("写入文件失败");
}
// 显式刷新缓冲区
fflush($fp);
flock($fp, LOCK_UN);
fclose($fp);
// 记录成功日志
error_log("[SUCCESS] 订单已写入,大小: {$bytes}字节", 3, "$document_root/web/orders/order.log");
echo "<p class='success'>订单处理成功!</p>";
} catch (RuntimeException $e) {
error_log("[ERROR] " . date('Y-m-d H:i:s') . " " . $e->getMessage(), 3, "$document_root/web/orders/error.log");
echo "<p class='error'>系统繁忙,请稍后重试</p>";
}
}
// 调用示例
writeOrderToFile($outputstring);
?>
PHP的 flock( ) 函数用于文件锁定,控制多进程并发访问,确保文件操作的原子性。其核心用法如下:
函数原型
bool flock(resource $handle, int $operation, int &$wouldblock = null)锁定模式
共享锁 (LOCK_SH) 允许多个进程同时读取文件,但阻止写入操作
独占锁 (LOCK_EX) 仅允许一个进程写入文件,其他进程无法读取或写入
非阻塞锁 (LOCK_NB) 可与LOCK_SH或LOCK_EX组合使用,避免阻塞进程
释放锁 (LOCK_UN) 显式释放文件锁
典型流程
$fp = fopen("file.txt", "a+");
if (flock($fp, LOCK_EX)) { // 获取独占锁
fwrite($fp, "Data to write");
flock($fp, LOCK_UN); // 释放锁
} else {
echo "获取锁失败";
}
fclose($fp);
评论