PHP中static关键字原理的学习研究分析


Posted in PHP onJuly 18, 2011

看PHP手册的时候发现了下面这样一段代码:

<?php 
function Test() 
{ 
static $count = 0; 
$count++; 
echo $count; 
if ($count < 10) { 
Test(); 
} 
$count--; 
} 
?>

执行结果如下:
这是一个递归的函数,声明的静态变量count记录次数,输出1~10。
我在看的时候有个疑惑,递归调用的时候 static $count = 0; 语句会重复执行,这为什么不会导致count变量被重复赋值呢?带着这个疑问和同事研究了一下,测试用代码如下:
<?php 
echo 'start<br />'; 
static $a = 10; 
echo "$a <br />"; 
unset($GLOBALS['a']); 
echo "$a <br />"; 
static $a = 20; 
echo "$a <br />"; 
$GLOBALS['a'] = 10; 
echo "$a <br />"; 
static $a = 30; 
echo "$a <br />"; 
unset($GLOBALS['a']); 
echo "$a <br />"; 
static $a; 
echo "$a <br />"; 
static $a = 40; 
echo "$a <br />"; 
$a = 100; 
echo "$a <br />"; 
static $a = 50; 
echo "$a <br />"; 
static $a = 4; 
echo "$a <br />"; 
echo 'end <br />'; 
exit; 
?>

执行结果如下:
start
  1. Notice: Undefined variable: a 
  2. 10 
  3. 10 
  4. Notice: Undefined variable: a 
  5. 10 
  6. 10 
  7. 100 
  8. 100 
  9. 100 
  10. end
(结果中关于文件位置的部分已删去。也可以去掉echo语句使用zend的debug功能查看,这样结果更清晰)

代码第5行第一次输出$a的值为4,由此推测PHP在页面初始化的时候分配静态变量的内存,此时使用了同一个变量的最后一次声明的值(这个可以把4改为其他数测试)。代码第7行调用unset函数销毁变量$a,再次输出$a的值时看到未定义变量的提示,说明变量已经被销毁。

第10行再次输出时,输出结果仍是4而不是20,有两种可能,一个是php再次初始化了$a的值,另一种是php使用了$a被销毁前的值,这个问题在第20行输出的时候解决。第16行$a销毁的时候值为10,第19行声明后输出仍为10。

第11行将$a的值修改为10,在14行再次声明$a,17行输出认为10。推测为重复声明时php还是使用静态变量内存中的值,而不再次赋值。

至此,手册中发现的问题,大致上已经解决了,即递归调用中的声明没有改变$count的值,所以递归在$count=10时成功停止。

可能有理解不正确的地方,欢迎拍砖。
PHP 相关文章推荐
定制404错误页面,并发信给管理员的程序
Oct 09 PHP
PHP 防恶意刷新实现代码
May 16 PHP
php设计模式 Mediator (中介者模式)
Jun 26 PHP
PHP字符串中特殊符号的过滤方法介绍
Feb 18 PHP
PHP include任意文件或URL介绍
Apr 29 PHP
php curl请求信息和返回信息设置代码实例
Apr 27 PHP
WIN8.1下搭建PHP5.6环境
Apr 29 PHP
PHP框架Laravel学习心得体会
Oct 28 PHP
简单谈谈php延迟静态绑定
Jan 26 PHP
PHP中字符串长度的截取用法示例
Jan 12 PHP
PHP simplexml_load_string()函数实例讲解
Feb 03 PHP
thinkPHP+LayUI 流加载实现功能
Sep 27 PHP
在WAMP环境下搭建ZendDebugger php调试工具的方法
Jul 18 #PHP
无法载入 mcrypt 扩展,请检查 PHP 配置终极解决方案
Jul 18 #PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
Jul 18 #PHP
PHP中英混合字符串截取函数代码
Jul 17 #PHP
PHP操作数组的一些函数整理介绍
Jul 17 #PHP
如何突破PHP程序员的技术瓶颈分析
Jul 17 #PHP
过滤掉PHP数组中的重复值的实现代码
Jul 17 #PHP
You might like
如何使用脚本模仿登陆过程
2006/11/22 PHP
深入解析fsockopen与pfsockopen的区别
2013/07/05 PHP
php获取本周开始日期和结束日期的方法
2015/03/09 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
PHP二维数组去重实例分析
2016/11/18 PHP
PHP单例模式实例分析【防继承,防克隆操作】
2019/05/22 PHP
Jquery $.getJSON 在IE下的缓存问题解决方法
2014/10/10 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
javascript二维数组转置实例
2015/01/22 Javascript
jQuery实现导航滚动到指定内容效果完整实例【附demo源码下载】
2016/09/20 Javascript
AngularJS自定义指令实现面包屑功能完整实例
2017/05/17 Javascript
详解vue axios中文文档
2017/09/12 Javascript
详解webpack 打包文件体积过大解决方案(code splitting)
2018/04/10 Javascript
JS正则表达式常见用法实例详解
2018/06/19 Javascript
JS实现可针对算术表达式求值的计算器功能示例
2018/09/04 Javascript
JavaScript模板引擎应用场景及实现原理详解
2018/12/14 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
js中比较两个对象是否相同的方法示例
2019/09/02 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
手把手15分钟搭一个企业级脚手架
2019/09/16 Javascript
JS 数组和对象的深拷贝操作示例
2020/06/06 Javascript
Python实现的下载网页源码功能示例
2017/06/13 Python
python学习教程之Numpy和Pandas的使用
2017/09/11 Python
Python多进程库multiprocessing中进程池Pool类的使用详解
2017/11/24 Python
python爬虫 urllib模块反爬虫机制UA详解
2019/08/20 Python
详解Django ORM引发的数据库N+1性能问题
2020/10/12 Python
施华洛世奇日本官网:SWAROVSKI日本
2018/05/04 全球购物
东南亚冒险旅行与活动:Adventoro
2019/10/16 全球购物
linux系统都有哪些运行级别
2012/04/15 面试题
鼓励运动员的广播稿
2014/02/08 职场文书
激情洋溢的毕业生就业求职信
2014/03/15 职场文书
小学关爱留守儿童活动方案
2014/08/25 职场文书
中职招生先进个人材料
2014/08/31 职场文书
2014年建筑工作总结
2014/11/26 职场文书
奥特曼十大神器:奥特手镯在榜,第一是贝利亚的神器
2022/03/18 日漫