Stack Overflow中的许多答案都使用fopen($file, "rw+")
,但manual没有列出"rw+"
模式,只有"r+"
模式(或"w+"
模式)。
所以我想知道, "rw+"
模式有什么作用? fopen($file,
"rw+"
或"r+"
之间的区别是什么?我之所以这样,是因为"rw+"
模式没有文档。
一种方法是考虑模式是添加,但我无法在fopen
手册页中找到任何关于组合模式的提及(此外,'将"r"
与"w+"
结合起来的意义,如果"w+"
已经使其可读?)。但最重要的是, w+
模式会截断文件,而rw+
不会截断文件(因此,它们不能添加)。尽管Stack Overflow用户使用它,但可能没有rw+
模式。也许它有效,因为解析器忽略了" w"字母,因为rw+
模式似乎是=== r+
?
澄清我的问题:什么是"rw+"
模式,也就是说,它与其他模式有何不同?我在评论中只收到两个答案:或者我应该检查文档(我已经检查并重新检查)和一个错误的答案,它表示它等于"w+"
(它不是&t; t)。 "w+"
会截断文件,而"rw+"
则不会。
这是一个用于测试的脚本(它证明w+
会截断文件,但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;
?>
答案 0 :(得分:68)
我认为你已经想到了这一点。虽然我猜,你想要权威的答案。
文档确实没有提及"rw+"
。然而,有更好的东西:PHP source code!
我很难尝试浏览源代码,直到找到PHP系列文章系列PHP开发人员的源代码(Part 1,Part 2,Part 3,{ {3}})。 我知道链接在两个网站之间跳转,那个系列就像那样。顺便说一句,我没有找到宣布的第5部分。
注意:这些文章很旧,他们在讨论PHP 5.4。
让我们看看fopen
实际上做了什么......让我们陷入兔子洞......
首先我们看看Part 4(我根据上面链接第2部分的建议找到了)。我注意到它使用function definition,我php_stream_open_wrapper_ex
,它只使用我们在found elsewhere中找到的_php_stream_open_wrapper_ex
。
_php_stream_open_wrapper_ex
对mode
做了什么? stream.c
寻找stream_opener
的定义将我带到It passes it to stream_opener
类型。
php_stream_wrapper_ops
in php_streams.h诱使我Searching for uses of the type php_stream_wrapper_ops
。
实际上有很多php_stream_wrapper_ops
的初始化允许打开不同的东西。我们正在查看php_fopen_wrapper.c,因为它的初始化为php_stream_wrapper_ops
,其中stream_opener
为php_plain_files_stream_opener
。
我们到了那里......
php_plain_files_stream_opener
是plain_wrapper.c。 further down in the same file
It delegates to php_stream_fopen_rel
使用_php_stream_fopen
。这是php_streams.h
defines php_stream_fopen_rel
。
最后,back on plain_wrapper.c。这将取出字符串并输出一些标志,耶!
让我们看看_php_stream_fopen
calls 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
,{{1} }。如果它识别出任何一个,它会设置适当的标志。否则我们有c
。
它在字符串中的某处查找FAILURE
并设置相应的标记。
它在字符串中的某处查找+
,e
和n
(取决于预处理程序指令)并设置相应的标记。
返回t
。
你问:
PHP中的fopen模式“r +”和“rw +”有什么区别?
无。 PHP只关心字符串以SUCCESS
开头并且有"r"
。 "+"
被忽略。
最后的注意事项:虽然很有可能与它一起玩并编写像"w"
这样的东西,但要小心,因为那些信可能有一天会有一些意义。它不会向前兼容。事实上,在某些情况下,"read+"
已经有了意义。相反,我建议,坚持文档。
感谢您借口查看PHP源代码。