PHP中fopen模式“r +”和“rw +”有什么区别?
在堆栈溢出使用fopen($file, "rw+")
许多答案,但手册没有列出"rw+"
模式,只有"r+"
模式(或"w+"
模式)。
所以我想知道, "rw+"
模式是做什么的? fopen($file,
"rw+"
或"r+"
什么区别?我这样问是因为在"rw+"
模式下没有文档。
一种方法是考虑到这些模式是加法的 ,但是在fopen
手册页中我找不到任何组合模式(除了"r"
"w+"
与"w+"
结合的意义是什么,如果"w+"
已经使它可读?)。 但最重要的是, w+
模式会截断文件,而rw+
不会截断它 (因此,它们不能被添加)。 可能没有rw+
模式,尽pipeStack Overflow用户使用它。 也许这是因为parsing器忽略了“w”字母,因为rw+
模式似乎是=== r+
?
为了澄清我的问题: 什么是"rw+"
模式 ,也就是说,它与其他模式有什么不同? 我在评论中只收到了两个答案:或者我应该检查文档(我已经检查并重新检查)和一个错误的答案,它说它等于"w+"
(不是)。 "w+"
截断文件,而"rw+"
不。
这是一个testing脚本(它certificatew+
截断文件,但rw+
不):
<?php $file = "somefile"; $fileOpened = fopen($file, "w"); fwrite($fileOpened, "0000000000000000000"); fclose($fileOpened); $fileOpened = fopen($file, "rw+"); fwrite($fileOpened, "data"); fclose($fileOpened); $fileOpened = fopen($file, "r"); $output = fgets($fileOpened); echo "First, with 'rw+' mode:<br>".$output; $fileOpened = fopen($file, "w+"); fwrite($fileOpened, "data"); fclose($fileOpened); $fileOpened = fopen($file, "r"); $output = fgets($fileOpened); echo "<br><br><br>Now with only 'w+' mode:<br>".$output; ?>
我想你已经明白了这一点。 虽然我猜,你想要权威的答案。
确实,文档没有提到"rw+"
。 然而,还有更好的东西: PHP源代码 !
兔子洞
我很难试图浏览源代码,直到我find文章系列PHP的PHP开发人员源代码( 第1 部分 , 第2 部分 , 第3 部分 , 第4部分 )。 我知道两个网站之间的链接跳转,那个系列就像那样。 顺便说一下,我没有find宣布的第5部分。
注意 :这些文章是老的,他们正在谈论PHP 5.4。
让我们看看fopen
究竟做了什么…让我们陷入兔子洞
首先我们看看函数的定义 (我发现上面的链接部分2的build议)。 我注意到它使用php_stream_open_wrapper_ex
,我在其他地方find它,它只是使用_php_stream_open_wrapper_ex
我们在stream.c中find。
_php_stream_open_wrapper_ex
用mode
做什么? 它将它传递给stream_opener
。
寻找stream_opener
的定义把我带到php_stream_wrapper_ops
中的typesphp_stream_wrapper_ops 。
searchphp_stream_wrapper_ops
types的用法使我变成了plain_wrapper.c 。
实际上有很多php_stream_wrapper_ops
的初始化允许打开不同的东西。 我们正在看php_fopen_wrapper.c,因为它有一个php_stream_wrapper_ops
的初始化,其中stream_opener
是php_plain_files_stream_opener
。
我们到了那里…
php_plain_files_stream_opener
进一步在同一个文件中 。 它委托给php_stream_fopen_rel
。
php_streams.h
使用_php_stream_fopen
定义php_stream_fopen_rel
。 这是在plain_wrapper.c 。
最后, _php_stream_fopen
调用php_stream_parse_fopen_modes
。 这将采取string和输出一些标志,耶!
仙境
让我们看看php_stream_parse_fopen_modes
:
PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags) { int flags; switch (mode[0]) { case 'r': flags = 0; break; case 'w': flags = O_TRUNC|O_CREAT; break; case 'a': flags = O_CREAT|O_APPEND; break; case 'x': flags = O_CREAT|O_EXCL; break; case 'c': flags = O_CREAT; break; default: /* unknown mode */ return FAILURE; } if (strchr(mode, '+')) { flags |= O_RDWR; } else if (flags) { flags |= O_WRONLY; } else { flags |= O_RDONLY; } #if defined(O_CLOEXEC) if (strchr(mode, 'e')) { flags |= O_CLOEXEC; } #endif #if defined(O_NONBLOCK) if (strchr(mode, 'n')) { flags |= O_NONBLOCK; } #endif #if defined(_O_TEXT) && defined(O_BINARY) if (strchr(mode, 't')) { flags |= _O_TEXT; } else { flags |= O_BINARY; } #endif *open_flags = flags; return SUCCESS; }
对于抽象,这就是它所做的(忽略细节):
-
它取
mode
的第一个字符,并检查它是否是r
,w
,a
,x
,c
。 如果它承认任何这些,它设置适当的标志。 否则,我们有一个FAILURE
。 -
它在string的某个地方查找并设置适当的标志。
-
它查找string中某处的
e
,n
和t
(取决于预处理器指令)并设置相应的标志。 -
回报
SUCCESS
。
回到现实世界
你问:
PHP中fopen模式“r +”和“rw +”有什么区别?
没有。 PHP只关心string以"r"
开始并且有一个"+"
。 "w"
被忽略。
最后说明 :虽然很喜欢玩这个游戏,写"read+"
类的东西,但要小心,因为这封信有一天会有一些意义。 它不会向前兼容。 实际上,在某些情况下, "e"
已经有了意义。 相反,我build议,坚持文件。
感谢您的借口来看看PHP源代码。