找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2706|回复: 3

【PHP】fopen()的坑

[复制链接]

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
发表于 2018-1-31 03:41:17 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
原帖网址:https://www.0xaa55.com/thread-16709-1-1.html
转载请保留出处。

注:此处所说的fopen()指的是PHP的fopen()函数而非C库的fopen()函数

在PHP官方文档的描述上我注意到有人用"rw"方式来打开文件,但这样写对不对呢?PHP的官方文档并没有说。
它的原文是:

phpfopen.png

那咋办?我们直接去看PHP源码就知道它是怎么实现的了。
传送门点此

然后注意观察,它是这样写的:
  1. /* parse standard "fopen" modes into open() flags */
  2. PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags)
  3. {
  4.         int flags;

  5.         switch (mode[0]) {
  6.                 case 'r':
  7.                         flags = 0;
  8.                         break;
  9.                 case 'w':
  10.                         flags = O_TRUNC|O_CREAT;
  11.                         break;
  12.                 case 'a':
  13.                         flags = O_CREAT|O_APPEND;
  14.                         break;
  15.                 case 'x':
  16.                         flags = O_CREAT|O_EXCL;
  17.                         break;
  18.                 case 'c':
  19.                         flags = O_CREAT;
  20.                         break;
  21.                 default:
  22.                         /* unknown mode */
  23.                         return FAILURE;
  24.         }

  25.         if (strchr(mode, '+')) {
  26.                 flags |= O_RDWR;
  27.         } else if (flags) {
  28.                 flags |= O_WRONLY;
  29.         } else {
  30.                 flags |= O_RDONLY;
  31.         }

  32. #if defined(O_CLOEXEC)
  33.         if (strchr(mode, 'e')) {
  34.                 flags |= O_CLOEXEC;
  35.         }
  36. #endif

  37. #if defined(O_NONBLOCK)
  38.         if (strchr(mode, 'n')) {
  39.                 flags |= O_NONBLOCK;
  40.         }
  41. #endif

  42. #if defined(_O_TEXT) && defined(O_BINARY)
  43.         if (strchr(mode, 't')) {
  44.                 flags |= _O_TEXT;
  45.         } else {
  46.                 flags |= O_BINARY;
  47.         }
  48. #endif

  49.         *open_flags = flags;
  50.         return SUCCESS;
  51. }
复制代码
它只判断“模式”的第一个字符,也就是mode[0],看它是r还是w还是a还是x还是c,然后决定打开方式——直接翻译成C库open()函数的功能。

也就是说,"rw"这种模式,里面的字母w是被无视掉的。效果等同于"r"。
既然这样……嘿嘿嘿,我要皮了。
  1. $fp = fopen("session.lock", "crap+"); // 读写模式打开或创建文件
  2. $fp = fopen("foo.txt", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr+"); // 读写模式打开文件
  3. $fp = fopen("bar.txt", "rabbit+"); // 读写模式打开文件
  4. $fp = fopen("baz.txt", "what th3 fuck"); // 写文件模式
  5. $fp = fopen("latest.log", "abcdEfghijklmNopqrsTuvwxyz"); // 写文件末尾模式
复制代码
皮这一下很开心。嗯。

参考资料:
http://php.net/manual/zh/function.fopen.php
https://stackoverflow.com/questi ... des-r-and-rw-in-php
https://github.com/php/php-src/b ... plain_wrapper.c#L66
http://man7.org/linux/man-pages/man2/open.2.html

回复

使用道具 举报

0

主题

6

回帖

23

积分

用户组: 初·技术宅

UID
3104
精华
0
威望
0 点
宅币
17 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2017-11-18
发表于 2018-2-1 13:14:42 | 显示全部楼层
abcdEfghijklmNopqrsTuvwxyz 写这么多有啥用,人家是strchar判断的
回复 赞! 靠!

使用道具 举报

1109

主题

1649

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24180 个
贡献
46222 次
宅之契约
0 份
在线时间
2294 小时
注册时间
2014-1-26
 楼主| 发表于 2018-2-1 15:28:22 | 显示全部楼层
思齐 发表于 2018-2-1 13:14
abcdEfghijklmNopqrsTuvwxyz 写这么多有啥用,人家是strchar判断的

是strchr不是strchar。
另外,写得多的话,比较皮。皮!懂不?
回复 赞! 靠!

使用道具 举报

0

主题

6

回帖

23

积分

用户组: 初·技术宅

UID
3104
精华
0
威望
0 点
宅币
17 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2017-11-18
发表于 2018-2-1 15:55:24 | 显示全部楼层
oooooooooooo
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-3-29 10:12 , Processed in 0.046583 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表