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 相关文章推荐
通过文字传递创建的图形按钮
Oct 09 PHP
WINXP下apache+php4+mysql
Nov 25 PHP
PHP远程连接MYSQL数据库非常慢的解决方法
Jul 05 PHP
php file_exists 检查文件或目录是否存在的函数
May 10 PHP
php提示undefined index的几种解决方法
May 21 PHP
ThinkPHP 表单自动验证运用示例
Oct 13 PHP
php画图实例
Nov 05 PHP
PHP和MySql中32位和64位的整形范围是多少
Feb 18 PHP
ThinkPHP表单令牌错误的相关解决方法分析
May 20 PHP
PHP执行shell脚本运行程序不产生core文件的方法
Dec 28 PHP
php语法检查的方法总结
Jan 21 PHP
PHP中->和=>的意思
Mar 31 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
用PHP调用Oracle存储过程的方法
2008/09/12 PHP
PHP sprintf() 函数的应用(定义和用法)
2012/06/29 PHP
如何使用php输出时间格式
2013/08/31 PHP
php将日期格式转换成xx天前的格式
2015/04/16 PHP
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
2015/08/23 PHP
解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
2015/10/23 PHP
PHP利用APC模块实现大文件上传进度条的方法
2015/10/29 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
PHP数据库操作三:redis用法分析
2017/08/16 PHP
js RuntimeObject() 获取ie里面自定义函数或者属性的集合
2010/11/23 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
javascript实现原生ajax的几种方法介绍
2013/09/21 Javascript
JS替换文本域内的回车示例
2014/02/18 Javascript
JS实现仿Windows7风格的网页右键菜单效果代码
2015/09/11 Javascript
js实现拖拽效果(构造函数)
2015/12/14 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
js实现小窗口拖拽效果
2016/12/03 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
2018/03/09 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
浅谈针对Vue相同路由不同参数的刷新问题
2018/09/29 Javascript
使用vue-router切换页面时实现设置过渡动画
2019/10/31 Javascript
js实现鼠标滑动到某个div禁止滚动
2020/09/17 Javascript
详解Python操作RabbitMQ服务器消息队列的远程结果返回
2016/06/30 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
对python实现合并两个排序链表的方法详解
2019/01/23 Python
python使用flask与js进行前后台交互的例子
2019/07/19 Python
python ctypes库2_指定参数类型和返回类型详解
2019/11/19 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
THE OUTNET美国官网:国际设计师品牌折扣网站
2017/03/07 全球购物
学习型党组织心得体会
2014/09/12 职场文书
房屋财产继承协议书范本
2014/11/03 职场文书
失职检讨书大全
2015/01/26 职场文书
追讨欠款律师函
2015/05/27 职场文书
党员转正介绍人意见
2015/06/03 职场文书