【PHP】fopen()的坑
原帖网址:https://www.0xaa55.com/thread-16709-1-1.html转载请保留出处。
注:此处所说的fopen()指的是PHP的fopen()函数而非C库的fopen()函数。
在PHP官方文档的描述上我注意到有人用"rw"方式来打开文件,但这样写对不对呢?PHP的官方文档并没有说。
它的原文是:
那咋办?我们直接去看PHP源码就知道它是怎么实现的了。
传送门点此
然后注意观察,它是这样写的:/* parse standard "fopen" modes into open() flags */
PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags)
{
int flags;
switch (mode) {
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,然后决定打开方式——直接翻译成C库open()函数的功能。
也就是说,"rw"这种模式,里面的字母w是被无视掉的。效果等同于"r"。
既然这样……嘿嘿嘿,我要皮了。$fp = fopen("session.lock", "crap+"); // 读写模式打开或创建文件
$fp = fopen("foo.txt", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr+"); // 读写模式打开文件
$fp = fopen("bar.txt", "rabbit+"); // 读写模式打开文件
$fp = fopen("baz.txt", "what th3 fuck"); // 写文件模式
$fp = fopen("latest.log", "abcdEfghijklmNopqrsTuvwxyz"); // 写文件末尾模式皮这一下很开心。嗯。
参考资料:
http://php.net/manual/zh/function.fopen.php
https://stackoverflow.com/questions/43797180/what-is-the-difference-between-fopen-modes-r-and-rw-in-php
https://github.com/php/php-src/blob/master/main/streams/plain_wrapper.c#L66
http://man7.org/linux/man-pages/man2/open.2.html
abcdEfghijklmNopqrsTuvwxyz 写这么多有啥用,人家是strchar判断的:$ 思齐 发表于 2018-2-1 13:14
abcdEfghijklmNopqrsTuvwxyz 写这么多有啥用,人家是strchar判断的
是strchr不是strchar。
另外,写得多的话,比较皮。皮!懂不? oooooooooooo
页:
[1]