PHP 中对变量unset,可以销毁变量中的资源
浏览:1968次 出处信息
提示: 您可以先看结论,结论在文章最后。
start...
我们先看两段代码:
以下是代码片段: <?php while($i++ < 1000) { $a = fsockopen("10.55.38.18",11211); unset($a); sleep(3); } ?> |
以下是代码片段: <?php while($i++ < 1000) { $a = fsockopen("10.55.38.18",11211); sleep(3); } ?> |
分析:
- 两段测试代码只有一个unset的区别,我们只是在测试unset是否是必要的
- 因为我们打开的连接根本就没有关闭,在变量被unset或被重新赋值时,该变量所使用的连接是否会自动关闭呢?如果不能自动关闭,代码一直运行将会产生大量的连接,这是我们最担心的。
- 其实我们完全可以不必做这种测试,我们可以在销毁变量前显示关闭连接的,我们也最好这么做,虽然多了几行代码,但是代码的可读性就提高了很多
1.strace -tt php a.php
10:57:43.474622 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 10:57:43.474705 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 10:57:43.474787 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 10:57:43.474898 connect(3, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("10.55.38.18")}, 16) = -1 EINPROGRESS (Operation now in progress) 10:57:43.474984 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1 10:57:43.523892 getsockopt(3, SOL_SOCKET, SO_ERROR, [29042414236729344], [4]) = 0 10:57:43.523974 fcntl(3, F_SETFL, O_RDWR) = 0 10:57:43.524046 close(3) = 0 10:57:43.524124 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 10:57:43.524201 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0 10:57:43.524269 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 10:57:43.524331 nanosleep({3, 0}, {3, 0}) = 0
2.分析:
strace -tt php b.php
11:13:24.554959 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 11:13:24.554998 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 11:13:24.555029 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 11:13:24.555063 connect(3, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("10.55.38.18")}, 16) = -1 EINPROGRESS (Operation now in progress) 11:13:24.555131 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1 11:13:24.615839 getsockopt(3, SOL_SOCKET, SO_ERROR, [339302416384], [4]) = 0 11:13:24.615924 fcntl(3, F_SETFL, O_RDWR) = 0 11:13:24.616017 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 11:13:24.616098 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0 11:13:24.616173 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 11:13:24.616250 nanosleep({3, 0}, {3, 0}) = 0 ... ... 11:13:27.618228 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4 11:13:27.618302 fcntl(4, F_GETFL) = 0x2 (flags O_RDWR) 11:13:27.618368 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0 11:13:27.618453 connect(4, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("10.55.38.18")}, 16) = -1 EINPROGRESS (Operation now in progress) 11:13:27.618598 poll([{fd=4, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1 11:13:27.676299 getsockopt(4, SOL_SOCKET, SO_ERROR, [339302416384], [4]) = 0 11:13:27.676381 fcntl(4, F_SETFL, O_RDWR) = 0 11:13:27.676679 close(3) = 0 11:13:27.676776 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 11:13:27.676858 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0 11:13:27.676934 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 11:13:27.677013 nanosleep({3, 0}, <unfinished ...>
- 测试1中,我们观察 4~8行,打开的连接时立即被关闭的,因为遇到了unset函数,说明: 在变量被unset时,变量所标示的连接立即关闭
- 测试2中,我们观察14~21行,发现打开的连接是4,但是关闭的连接是3,但是3是上次sleep之前的一个连接,说明: 在变量被重新赋值时,变量所标示的连接立即关闭
- 在变量被重新赋值时,变量所标示的连接立即关闭
- 在变量被unset时,变量所标示的连接立即关闭
- 不要写这么含蓄的代码。
- 如果你是一个连接变量,重新赋值前最好close一下;
- 如果你是一个对象,在析构函数中关闭你的连接;当然如果你使用的是长连接,就不必这么做了
建议继续学习:
- Axure之变量的使用 (阅读:4187)
- 从shell中向awk传递变量实例 (阅读:3600)
- 深入PHP使用技巧之变量 (阅读:3571)
- 变量在内存中的位置 (阅读:2977)
- Linux的shell变量 (阅读:2682)
- c语言全局变量和局部变量问题汇总 (阅读:2692)
- PHP的可变变量名 (阅读:2252)
- 详解Linux bash中的变量 (阅读:2017)
- 如何获取一个变量的名字 (阅读:1885)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:新浪微博OAuth认证流程分析
后一篇:自动检测字符编码函数mb_detect_encoding >>
文章信息
- 作者:phpor 来源: PHPor 的Blog
- 标签: unset 变量
- 发布时间:2010-11-24 21:12:47
建议继续学习
近3天十大热文
- [54] IOS安全–浅谈关于IOS加固的几种方法
- [52] android 开发入门
- [52] 如何拿下简短的域名
- [51] 图书馆的世界纪录
- [49] Go Reflect 性能
- [49] Oracle MTS模式下 进程地址与会话信
- [47] 【社会化设计】自我(self)部分――欢迎区
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [37] 程序员技术练级攻略
- [29] 视觉调整-设计师 vs. 逻辑