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

看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时成功停止。

可能有理解不正确的地方,欢迎拍砖。

(0)

相关推荐

  • 深入理解PHP中的static和yield关键字

    前言 本文主要给大家介绍了关于PHP中static和yield关键字的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 先来说说 static 关键字.本篇只讲静态方法的使用与后期绑定的知识点. static 什么时候用来修饰方法 static 关键字大家都知道是用来修饰方法与属性的. 那么大家在项目中会在哪些场景下使用它? 我遇到过几个项目,要求所有的方法全部 static 化,当然控制器方法不能这么干.原因之一就是:静态方法执行效率高?那么我们基于此来分析一下. 首

  • php中static和const关键字用法分析

    本文实例讲述了php中static和const关键字用法.分享给大家供大家参考,具体如下: static关键字在类中描述的成员属性和成员函数都是静态的. static成员能限制外部的访问,因为static成员是属于类的,而不是属于任何对象实例. 从内存的角度讲,其中对象是放在"堆内存"中,对象的引用是放在"栈内存"中,而静态成员被放在初始化静态段中,在类的第一次加载的时候加入的.可以让对内存中的所有对象所共享.如下图所示: <?php class Person

  • php类中的$this,static,final,const,self这几个关键字使用方法

    本篇文章主要分项了一下关于php类中的$this,static,final,const,self这几个关键字使用方法. $this $this表示当前实例,在类的内部方法访问未声明为const及static的属性时,使用$this->value='phpernote';的形式.常见用法如: $this->属性 $this->方法 举例如下: <?php class MyClass{ private $name; public function __construct($name){

  • 理解PHP5中static和const关键字的区别

    PHP5中加入了很多面向对象的思想,PHP5的面向对象比较接近Java的面向对象思想.我们这里对PHP5中的static和const关键字作用进行一下描述,希望对学习PHP5的朋友有帮助. (1) static static关键字在类中是,描述一个成员是静态的,static能够限制外部的访问,因为static后的成员是属于类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心保护.类的静态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样的,类

  • PHP中static关键字以及与self关键字的区别

    概述 正在学习设计模式,之前有一篇文章关于单例模式的文章,重新读了这篇文章,发现对static关键字掌握不是很牢靠,重新温习一下. static关键字 PHP手册里对static关键字的介绍如下: 复制代码 代码如下: Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as

  • 开启PHP Static 关键字之旅模式

    声明类成员或方法为static,就可以不实例化类而直接访问.不能通过一个对象来访问其中的静态成员(静态方法除外). 为了兼容PHP4,如果没有指定"可见性",属性和方法默认为public. 由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用. 静态属性不可以由对象通过->操作符来访问. 用::方式调用一个非静态方法会导致一个E_STRICT级别的错误. 就像其它所有的PHP静态变量一样,静态属性只能被初始化为一个字符值或一个常量,不能使用表达式. 所以你可

  • php面向对象全攻略 (十) final static const关键字的使用

    14.final 关键字的应用 这个关键字只能用来定义类和定义方法,不能使用final 这个关键字来定义成员属性,因 为final 是常量的意思,我们在PHP 里定义常量使用的是define()函数,所以不能使用final 来 定义成员属性. 使用final 关键标记的类不能被继承: 代码片段 final class Person{ - - } class Student extends Person{ } 会出现下面错误: Fatal error: Class Student may not

  • php Static关键字实用方法

    为了兼容PHP4,如果没有指定"可见性",属性和方法默认为public. 由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用. 静态属性也可以由对象通过->操作符来访问. 用::方式调用一个非静态方法会导致一个E_STRICT级别的错误. 就像其它所有的PHP静态变量一样,静态属性只能被初始化为一个字符值或一个常量,不能使用表达式. 所以你可以把静态属性初始化为整型或数组,但不能指向另一个变量或函数返回值,也不能指向一个对象. PHP5.3.0之后,我们可

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

    看PHP手册的时候发现了下面这样一段代码: 复制代码 代码如下: <?php function Test() { static $count = 0; $count++; echo $count; if ($count < 10) { Test(); } $count--; } ?> 执行结果如下: 这是一个递归的函数,声明的静态变量count记录次数,输出1~10. 我在看的时候有个疑惑,递归调用的时候 static $count = 0; 语句会重复执行,这为什么不会导致count变

  • 详解Java中static关键字的使用和原理

    目录 概述 定义和使用格式 类变量 静态方法 调用格式 静态原理图解 静态代码块 概述 关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属 于某个对象的.也就是说,既然属于类,就可以不靠创建对象来调用了. 定义和使用格式 类变量 当 static 修饰成员变量时,该变量称为类变量.该类的每个对象都共享同一个类变量的值.任何对象都可以更改 该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作. 类变量:使用 static关键字修

  • Java静态static关键字原理详解

    这篇文章主要介绍了Java静态static关键字原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 static关键字既可以修饰成员变量,也可以修改成员方法,修饰的成员变量和成员方法可以直接通过类名调用,也可以通过对象调用(其实即使是通过对象调用,也会被翻译成类名调用),建议通过类名调用. 成员方法用static修饰后,就成为了静态方法,静态方法不属于对象,而是属于类. 注意事项: 1.静态方法中不能使用this,因为this指的是当前对象

  • 浅谈Java中static关键字的作用

    static关键字主要有两种作用: 第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 具体而言,在Java语言中,static主要有4中使用情况:成员变量.成员方法.代码块和内部类 (1)static成员变量: Java类提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量.静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使

  • 带你了解Java中Static关键字的用法

    目录 Java中Static关键字的一些用法详解 1. Static 修饰类属性,因为静态成员变量可以通过类名+属性名调用,非静态成员变量不能通过类名+属性名调用: 2. Static 修饰类方法,可以通过类名.静态方法名的方式调用静态方法,不可以用类名.静态方法名调用非静态方法: 3. 静态代码块,匿名代码块,构造函数.三者的调用顺序为(静态代码块(只调用1次) --> 匿名代码块 --> 构造函数). 总结 Java中Static关键字的一些用法详解 1. Static 修饰类属性,因为静

  • 详解Java中static关键字和内部类的使用

    目录 一. static 关键字 1. static修饰成员变量 2. static修饰成员方法 3. static成员变量的初始化 二. 内部类 1. 实例内部类 2. 静态内部类 3. 局部内部类 4. 匿名内部类 一. static 关键字 在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的. 1. static修饰成员变量 static修饰的成员变量,称为静态成员变量 [静态成员变量特性]: 不属于某个具体的对象,是类的属

  • java中static关键字用法详解

    前言 static对我们来说并不陌生,也是面试经常碰到的问题,今天抽空整理了一篇总结作为笔记保存起来! static用法可以分为三大块:静态变量.静态方法.静态代码块,下面将从这三个方面分析 静态方法 通常在一个类中定义一个方法为static,即为静态方法,无需本类的对象即可调用此方法 声明为static的方法有要注意以下几点: · 它们仅能调用其他的static方法. · 它们只能访问static变量. · 它们不能以任何方式引用this或super. public class MainCla

  • 详解Java编程中static关键字和final关键字的使用

    Java static关键字以及Java静态变量和静态方法 static 修饰符能够与变量.方法一起使用,表示是"静态"的. 静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法.静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同. 请看下面的例子: public class Demo { static int i = 10; int j; Demo() { this.j

  • 关于C/C++中static关键字的作用总结

    1.先来介绍它的第一条也是最重要的一条:隐藏.(static函数,static变量均可)当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.举例来说明.同时编译两个源文件,一个是a.c,另一个是main.c. 复制代码 代码如下: //a.cchar a = 'A';               // global variablevoid msg(){     printf("Hello\n");} 复制代码 代码如下: //main.c int main

随机推荐