技术宅的结界

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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 202|回复: 3
收起左侧

【PHP】fopen()的坑

[复制链接]

993

主题

2190

帖子

5万

积分

用户组: 管理员

一只技术宅

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

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

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

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

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

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

phpfopen.png

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

然后注意观察,它是这样写的:
[C] 纯文本查看 复制代码
/* parse standard "fopen" modes into open() flags */
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[0],看它是r还是w还是a还是x还是c,然后决定打开方式——直接翻译成C库open()函数的功能。

也就是说,"rw"这种模式,里面的字母w是被无视掉的。效果等同于"r"。
既然这样……嘿嘿嘿,我要皮了。
[PHP] 纯文本查看 复制代码
$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/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判断的

993

主题

2190

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16151 个
贡献
31382 次
宅之契约
0 份
在线时间
1543 小时
注册时间
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, 2018-7-17 00:41 , Processed in 0.081126 second(s), 20 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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