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 相关文章推荐
echo, print, printf 和 sprintf 区别
Dec 06 PHP
特详细的PHPMYADMIN简明安装教程
Aug 01 PHP
smarty自定义函数htmlcheckboxes用法实例
Jan 22 PHP
phalcon框架使用指南
Feb 23 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
Mar 17 PHP
PHP中类的继承和用法实例分析
May 24 PHP
ThinkPHP打水印及设置水印位置的方法
Oct 14 PHP
Laravel接收前端ajax传来的数据的实例代码
Jul 20 PHP
PHP接口继承及接口多继承原理与实现方法详解
Oct 18 PHP
Laravel 实现密码重置功能
Feb 23 PHP
laravel 实现设置时区的简单方法
Oct 10 PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 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
饭制《星际争霸》Mod:优化游戏机制 增加新单位
2017/07/02 星际争霸
使用xampp搭建运行php虚拟主机的详细步骤
2015/10/21 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
ASP小贴士/ASP Tips javascript tips可以当桌面
2009/12/10 Javascript
js控制滚动条缓慢滚动到顶部实现代码
2013/03/20 Javascript
JS判断表单输入是否为空(示例代码)
2013/12/23 Javascript
使用 js+正则表达式为关键词添加链接
2014/11/11 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
原生JS和JQuery动态添加、删除表格行的方法
2015/05/28 Javascript
Bootstrap每天必学之js插件
2015/11/30 Javascript
jQuery实现的网格线绘制方法
2016/06/20 Javascript
jQuery实现圣诞节礼物动画案例解析
2016/12/25 Javascript
JavaScript实现经典排序算法之冒泡排序
2016/12/28 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
BootStrap 弹出层代码
2017/02/09 Javascript
JavaScript的级联函数用法简单示例【链式调用】
2019/03/26 Javascript
javascript网页随机点名实现过程解析
2019/10/15 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
WebStorm中如何将自己的代码上传到github示例详解
2020/10/28 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
python多线程http下载实现示例
2013/12/30 Python
基于python实现微信模板消息
2015/12/21 Python
Windows下Python2与Python3两个版本共存的方法详解
2017/02/12 Python
快速了解Python开发中的cookie及简单代码示例
2018/01/17 Python
Python函数装饰器实现方法详解
2018/12/22 Python
使用python将多个excel文件合并到同一个文件的方法
2019/07/09 Python
python实现QQ邮箱发送邮件
2020/03/06 Python
Python 炫技操作之合并字典的七种方法
2020/04/10 Python
HTML5移动端手机网站开发流程
2016/04/25 HTML / CSS
REISS美国官网:伦敦最受欢迎的时尚品牌
2019/08/16 全球购物
PHP如何对用户密码进行加密
2014/07/31 面试题
请问软件开发中的设计模式你会使用哪些
2015/05/13 面试题
国际贸易专业推荐信
2013/11/15 职场文书
购房协议书范本
2014/04/11 职场文书
远程网络教育毕业生自我鉴定
2014/04/14 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书