开发者社区 问答 正文

fopen 写文件叠加的问题, 求指教.:报错

function __fopen($path){
    static $fp;  //函数体的工厂模式.
    
    if($fp)
        return $fp;
    
    $fp = fopen($path, 'w+b');
    return $fp;
}


$fp = __fopen('./a.txt'); // 取得文件句柄是一样的.
fwrite($fp ,'a-');

$fp = __fopen('./a.txt'); // 取得文件句柄是一样的.
fwrite($fp ,'b-');


echo file_get_contents('./a.txt');
// output: a-b-;

求解释怎么理解这操作, 我用w+b全新写入模式, 为什么数据还叠回写入了.

展开
收起
kun坤 2020-06-14 08:52:55 485 分享 版权
阿里云 AI 助理回答

这段代码中,您定义了一个名为__fopen的函数,它使用了静态变量$fp来实现类似单例模式的功能,确保每次调用该函数时都返回同一个文件句柄。这里的关键在于理解PHP的文件操作模式以及静态变量的作用。

首先,关于文件操作模式'w b': - 'w' 表示写入模式,如果文件已存在则会被截断(即清空原有内容),如果文件不存在则尝试创建。 - 'b' 是二进制模式,在某些系统上对文件进行二进制读写时需要加上这个标志,但在PHP中通常这不是必需的,除非你处理的是非文本的二进制数据。在您的上下文中,加不加'b'实际上对问题影响不大,因为主要关注点是文件被截断的问题。

然后,关于静态变量static $fp;: - 静态变量仅在第一次声明它的函数调用中初始化,之后的调用会保留其值。这意味着第二次及以后调用__fopen时,不会重新创建文件句柄,而是直接返回之前已经打开的文件句柄。

现在解释输出结果a-b-的原因:

  1. 第一次调用__fopen('./a.txt')时,由于$fp尚未初始化,所以会执行fopen($path, 'w b'),此时文件a.txt被创建(如果不存在)或截断(如果已存在),然后写入'a-'
  2. 第二次调用__fopen('./a.txt')时,由于$fp已经是打开状态(由静态变量保持),函数直接返回这个现有的文件句柄,而不会再次执行fopen去截断文件。因此,文件a.txt没有被清空,接着向同一个文件追加写入'b-'

最终,文件a.txt的内容是两次写入的结果,即a-b-

总结:尽管您使用了写入模式'w',理论上每次打开都会清空文件,但由于静态变量的特性,第二次调用时并没有实际重新打开文件,从而避免了文件内容被截断,导致了数据的累加写入。如果您希望每次调用都独立写入并覆盖原文件内容,应避免使用静态变量存储文件句柄,或者在每次写入前显式关闭文件句柄。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
PHP
问答地址: