技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> PHP --> PHP 中对变量unset,可以销毁变量中的资源

PHP 中对变量unset,可以销毁变量中的资源

浏览:2022次  出处信息

提示: 您可以先看结论,结论在文章最后。

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);        
    }        
            
    ?>    

分析:

        
  1. 两段测试代码只有一个unset的区别,我们只是在测试unset是否是必要的    
  2. 因为我们打开的连接根本就没有关闭,在变量被unset或被重新赋值时,该变量所使用的连接是否会自动关闭呢?如果不能自动关闭,代码一直运行将会产生大量的连接,这是我们最担心的。    
  3. 其实我们完全可以不必做这种测试,我们可以在销毁变量前显示关闭连接的,我们也最好这么做,虽然多了几行代码,但是代码的可读性就提高了很多
测试
1.
strace  -tt php a.php
        
  1.     
    10:57:43.474622 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
            
  2.     
    10:57:43.474705 fcntl(3, F_GETFL)       = 0x2 (flags O_RDWR)
            
  3.     
    10:57:43.474787 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
            
  4.     
    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)
            
  5.     
    10:57:43.474984 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1
            
  6.     
    10:57:43.523892 getsockopt(3, SOL_SOCKET, SO_ERROR, [29042414236729344], [4]) = 0
            
  7.     
    10:57:43.523974 fcntl(3, F_SETFL, O_RDWR) = 0
            
  8.     
    10:57:43.524046 close(3)                = 0
            
  9.     
    10:57:43.524124 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
            
  10.     
    10:57:43.524201 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
            
  11.     
    10:57:43.524269 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
            
  12.     
    10:57:43.524331 nanosleep({3, 0}, {3, 0}) = 0
        

2.
strace  -tt php b.php
        
  1.     
    11:13:24.554959 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
            
  2.     
    11:13:24.554998 fcntl(3, F_GETFL)       = 0x2 (flags O_RDWR)
            
  3.     
    11:13:24.555029 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
            
  4.     
    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)
            
  5.     
    11:13:24.555131 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1
            
  6.     
    11:13:24.615839 getsockopt(3, SOL_SOCKET, SO_ERROR, [339302416384], [4]) = 0
            
  7.     
    11:13:24.615924 fcntl(3, F_SETFL, O_RDWR) = 0
            
  8.     
    11:13:24.616017 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
            
  9.     
    11:13:24.616098 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
            
  10.     
    11:13:24.616173 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
            
  11.     
    11:13:24.616250 nanosleep({3, 0}, {3, 0}) = 0
            
  12.     
    ...
            
  13.     
    ...
            
  14.     
    11:13:27.618228 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
            
  15.     
    11:13:27.618302 fcntl(4, F_GETFL)       = 0x2 (flags O_RDWR)
            
  16.     
    11:13:27.618368 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
            
  17.     
    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)
            
  18.     
    11:13:27.618598 poll([{fd=4, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 60000) = 1
            
  19.     
    11:13:27.676299 getsockopt(4, SOL_SOCKET, SO_ERROR, [339302416384], [4]) = 0
            
  20.     
    11:13:27.676381 fcntl(4, F_SETFL, O_RDWR) = 0
            
  21.     
    11:13:27.676679 close(3)                = 0
            
  22.     
    11:13:27.676776 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
            
  23.     
    11:13:27.676858 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
            
  24.     
    11:13:27.676934 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
            
  25.     
    11:13:27.677013 nanosleep({3, 0},  <unfinished ...>
        
分析:
        
  1. 测试1中,我们观察 4~8行,打开的连接时立即被关闭的,因为遇到了unset函数,说明: 在变量被unset时,变量所标示的连接立即关闭    
  2. 测试2中,我们观察14~21行,发现打开的连接是4,但是关闭的连接是3,但是3是上次sleep之前的一个连接,说明: 在变量被重新赋值时,变量所标示的连接立即关闭
结论:
        
  1. 在变量被重新赋值时,变量所标示的连接立即关闭    
  2. 在变量被unset时,变量所标示的连接立即关闭    
  3. 不要写这么含蓄的代码。
        
              
    • 如果你是一个连接变量,重新赋值前最好close一下;        
    • 如果你是一个对象,在析构函数中关闭你的连接;当然如果你使用的是长连接,就不必这么做了    

建议继续学习:

  1. Axure之变量的使用    (阅读:4207)
  2. 从shell中向awk传递变量实例    (阅读:3618)
  3. 深入PHP使用技巧之变量    (阅读:3617)
  4. 变量在内存中的位置    (阅读:2989)
  5. Linux的shell变量    (阅读:2693)
  6. c语言全局变量和局部变量问题汇总    (阅读:2704)
  7. PHP的可变变量名    (阅读:2301)
  8. 详解Linux bash中的变量    (阅读:2068)
  9. 如何获取一个变量的名字    (阅读:1940)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1