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全新写入模式, 为什么数据还叠回写入了.
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
这段代码中,您定义了一个名为__fopen
的函数,它使用了静态变量$fp
来实现类似单例模式的功能,确保每次调用该函数时都返回同一个文件句柄。这里的关键在于理解PHP的文件操作模式以及静态变量的作用。
首先,关于文件操作模式'w b'
: - 'w'
表示写入模式,如果文件已存在则会被截断(即清空原有内容),如果文件不存在则尝试创建。 - 'b'
是二进制模式,在某些系统上对文件进行二进制读写时需要加上这个标志,但在PHP中通常这不是必需的,除非你处理的是非文本的二进制数据。在您的上下文中,加不加'b'实际上对问题影响不大,因为主要关注点是文件被截断的问题。
然后,关于静态变量static $fp;
: - 静态变量仅在第一次声明它的函数调用中初始化,之后的调用会保留其值。这意味着第二次及以后调用__fopen
时,不会重新创建文件句柄,而是直接返回之前已经打开的文件句柄。
现在解释输出结果a-b-
的原因:
__fopen('./a.txt')
时,由于$fp
尚未初始化,所以会执行fopen($path, 'w b')
,此时文件a.txt
被创建(如果不存在)或截断(如果已存在),然后写入'a-'
。__fopen('./a.txt')
时,由于$fp
已经是打开状态(由静态变量保持),函数直接返回这个现有的文件句柄,而不会再次执行fopen
去截断文件。因此,文件a.txt
没有被清空,接着向同一个文件追加写入'b-'
。最终,文件a.txt
的内容是两次写入的结果,即a-b-
。
总结:尽管您使用了写入模式'w'
,理论上每次打开都会清空文件,但由于静态变量的特性,第二次调用时并没有实际重新打开文件,从而避免了文件内容被截断,导致了数据的累加写入。如果您希望每次调用都独立写入并覆盖原文件内容,应避免使用静态变量存储文件句柄,或者在每次写入前显式关闭文件句柄。