Stack Overflow中的许多答案都在使用fopen($file, "rw+"),但是手册没有列出"rw+"模式,只有"r+"模式(或"w+"模式).
所以我想知道,什么是"rw+"模式呢?fopen($file, "rw+"或者有"r+"什么区别?我问这个是因为没有关于该"rw+"模式的文档.
一种方法是考虑所述模式为添加剂,但我找不到在结合模式的任何提及fopen手册页(此外,什么是相结合的意义"r"与"w+",如果"w+"已经使其可读?).但最重要的是,w+模式截断文件,rw+而不截断它(因此,它们不能是加法的).rw+尽管Stack Overflow用户使用它,但可能没有模式.也许它有效,因为解析器忽略了"w"字母,因为rw+模式似乎是=== r+?
澄清我的问题:什么是"rw+"模式,即它与其他模式有何不同?我只在评论中收到两个答案:要么我应该检查文档(我已经检查并重新检查)和一个错误的答案,它说它等于"w+"(它不是)."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;
?>
Run Code Online (Sandbox Code Playgroud)
The*_*aot 68
我想你几乎已经弄明白了.虽然我猜,你想要权威的答案.
确实,文档没有提到"rw+".然而,还有更好的东西:PHP源代码!
我很难尝试浏览源代码,直到找到PHP PHP开发人员的PHP源代码系列文章(第1 部分,第2 部分,第3 部分,第4部分).我知道链接在两个站点之间跳转,那个系列就像那样.顺便说一句,我没有找到宣布的第5部分.
注意:那些文章很旧,他们在讨论PHP 5.4.
让我们看看究竟fopen做了什么......让我们陷入兔子洞......
首先,我们看一下函数定义(我根据上面链接的第2部分的建议找到了它).我注意到它的使用php_stream_open_wrapper_ex,我在其他地方发现,它只是使用_php_stream_open_wrapper_ex我们在stream.c中找到的.
怎么_php_stream_open_wrapper_ex办mode?它将它传递给stream_opener.
寻找定义stream_opener带我到php_stream_wrapper_opsphp_streams.h中的类型.
搜索该类型的用途导致php_stream_wrapper_ops我使用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.hphp_stream_fopen_rel通过使用定义_php_stream_fopen.这是关于plain_wrapper.c的.
最后,_php_stream_fopen打电话php_stream_parse_fopen_modes.哪个会带字符串并输出一些标志,耶!
我们来看看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;
}
Run Code Online (Sandbox Code Playgroud)
对于抽象,这是它的作用(忽略细节):
它采用的第一个字符mode并检查它是否是r,w,a,x,c.如果它识别出任何一个,它会设置适当的标志.否则我们有一个FAILURE.
它+在字符串中的某处查找并设置适当的标志.
它会查找e,n和t(取决于预处理器指令)的字符串的地方,并设置相应的标志.
返回SUCCESS.
您询问:
PHP中的fopen模式"r +"和"rw +"有什么区别?
没有.PHP只关心字符串的开头"r"并且有一个"+".该"w"被忽略.
最后的注意事项:尽管玩它很有吸引力并写下类似的东西"read+",但要小心,因为那些字母有一天会有一些意义.它不会向前兼容.事实上,在某些情况下,"e"已经有了意义.相反,我建议,坚持文档.
感谢借口来看看PHP源代码.