<?php
function msg() {
static $a = 0;
echo $a++, '<br />';
} msg();
msg();
msg();

上述代码,分别输出0,1,2 静态变量$a在第一次定义并初始化后就会常驻内存,直到脚本执行完毕。

当第二次调用msg()函数时,这时的$a值为1,而不会变成0。
 
那么问题来了,请看下面的一段代码:
$data = array(
array('id' => 1, 'title' => '衣服', 'parent' => 0),
array('id' => 2, 'title' => '鞋子', 'parent' => 0),
array('id' => 3, 'title' => '衬衫', 'parent' => 1),
array('id' => 4, 'title' => 'T恤', 'parent' => 1),
array('id' => 5, 'title' => '运动鞋', 'parent' => 2),
array('id' => 6, 'title' => '休闲鞋', 'parent' => 2),
); $data2 = array(
array('id' => 1, 'title' => '食物', 'parent' => 0),
array('id' => 2, 'title' => '肉食', 'parent' => 1),
array('id' => 3, 'title' => '素食', 'parent' => 1),
array('id' => 4, 'title' => '牛肉', 'parent' => 2),
array('id' => 5, 'title' => '面条', 'parent' => 3),
array('id' => 6, 'title' => '馒头', 'parent' => 3),
); //生成树型数据
function genTree($items, $id = 'id', $pid = 'parent', $son = 'child') {
$tree = array();
$tmpMap = array(); foreach ($items as $item) {
$tmpMap[$item[$id]] = $item;
}
foreach ($items as $item) {
if (isset($tmpMap[$item[$pid]])) {
$tmpMap[$item[$pid]][$son][] = &$tmpMap[$item[$id]];
} else {
$tree[] = &$tmpMap[$item[$id]];
}
}
unset($tmpMap);
return $tree;
} //通过给定数据,返回option的字符串,用于select下拉框
function getOpts($data, $idArr = array(), $level = 0, $son = 'child') {
static $opt = '';
if (!empty($data)) {
foreach ($data as $k => $v) {
$opt .= '<option value=' . $v['id'] . (in_array($v['id'], $idArr) ? ' selected="true"' : '') . '>' . str_repeat(' ', $level * 3) . $v['title'] . '</option>';
if (!empty($v[$son])) {
getOpts($v[$son], $idArr, $level + 1, $son);
}
}
}
return $opt;
} $data = genTree($data);
echo '<select>';
//第一次调用getOpts时,没有任何问题。
echo getOpts($data);
echo '</select>'; $data2 = genTree($data2);
echo '<select>';
//当第二次调用时,问题就出现了,还留有上次的数据
echo getOpts($data2);
echo '</select>';
上述问题,对于可能多次调用的函数,不建议在内部使用静态变量。
修改getOpts函数如下,从函数参数引入一个外部变量的引用,来解决此问题。
function getOpts($data, $idArr = array(), &$opt = '', $level = 0, $son = 'child') {
if (!empty($data)) {
foreach ($data as $k => $v) {
$opt .= '<option value=' . $v['id'] . (in_array($v['id'], $idArr) ? ' selected="true"' : '') . '>' . str_repeat(' ', $level * 3) . $v['title'] . '</option>';
if (!empty($v[$son])) {
getOpts($v[$son], $idArr, $opt, $level + 1, $son);
}
}
}
} $data = genTree($data);
getOpts($data, array(), $opt);
echo '<select>';
echo $opt;
echo '</select>'; $data2 = genTree($data2);
getOpts($data2, array(), $opt2);
echo '<select>';
echo $opt2;
echo '</select>';

php 函数中静态变量的问题的更多相关文章

  1. C++类中静态变量和普通变量的区别

    静态变量: 1.静态变量会被编到程序的exe里面,从程序启动到结束,它一直存在: 2.静态变量的初始化值为0: 3.全局变量默认是静态变量: 4.在类中的函数变量前面加了static的也是静态变量,只 ...

  2. Qt中静态变量使用方法

    静态变量可以在各个页面之前使用 先定义一个用于存放静态变量的类 例如datavar 在datavar.h中添加如下代码 #ifndef DATAVAR_H #define DATAVAR_H #inc ...

  3. 函数中声明变量不用Var的情况

    我们都知道函数中声明变量不用Var时这个变量会成为全局变量,但是并不是函数一开始执行就会把它变为全局变量,必须执行到这条语句. 看一段代码 function f(){    alert(a);    ...

  4. django变量使用-在模板中使用视图函数中的变量

    DTL语言,即django template language 第一次使用时,需要修改项目的setting.py文件,将其中TEMPLATES中的DIRS修改为os.path.join(BASE_DI ...

  5. Java中静态变量的声明位置

    Java中静态变量只能是成员变量,局部方法中的局部变量除final外不能有任何其他修饰符,例如: public class Test { static String x = "1" ...

  6. 谈谈java中静态变量与静态方法在有继承关系的两个类中调用

    谈谈java中静态变量与静态方法在有继承关系的两个类中调用 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量和静态方法在有继承关系的两个类中的问题测试 ...

  7. Java 中静态变量和实例变量区别

    Java 中静态变量和实例变量区别 静态变量属于类,该类不生产对象,通过类名就可以调用静态变量. 实例变量属于该类的对象,必须产生该类对象,才能调用实例变量. 在程序运行时的区别: 实例变量属于某个对 ...

  8. OpenCV-Python setMouseCallback回调函数中图像变量img的传递方法解析

    ☞ ░ 前往老猿Python博文目录 ░ 一.使用全局变量进行变量传递 OpenCV-Python中可以使用setMouseCallback来设置鼠标事件的回调函数,我们来看个样例. 1.1.案例1代 ...

  9. 第5.4节 Python函数中的变量及作用域

    一.函数中的变量使用规则 函数执行时,使用的全局空间是调用方的全局空间,参数及函数使用的局部变量存储在函数单独的局部名字空间内: 函数的形参在函数中修改了值时,并不影响调用方本身的数据,但如果形参是一 ...

随机推荐

  1. 不重启修改'log_slave_updates'变量

    Variable 'log_slave_updates' is a read only variable 不重启修改mysql变量 执行复制的时候遇到的问题 mysql> show variab ...

  2. Oracle跨库复制表结构

    1.首先建立远程连接 create public database link LINK_SJPSconnect to system identified by manager using '(DESC ...

  3. IIS7根据PID查找对应的站点

    runas /user:administrator cmd cd \Windows\System32\inetsrv appcmd.exe list wp

  4. CSS个人笔记

    1. CSS盒模型 1.1 控制元素尺寸属性 1.1.1 box-sizing: 改变元素应用的尺寸规则 当设置元素尺寸宽度为固定值时(eg: 100px), 其实是元素内容区域的宽度为100px, ...

  5. python中键值叫唤例子

    >>> myDict = {'a':'A','b':'B','c':'C'} >>> myDict {'a': 'A', 'c': 'C', 'b': 'B'} & ...

  6. spring中 的MD5 加密

    //对密码进行加密(不需要使用其他Md5工具  .spring中有 在digestUtils)        String password = DigestUtils.md5DigestAsHex( ...

  7. 简单ssh建立 (paramiko)

    SSH为建立在应用层和传输层基础上的安全协议.SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议.利用SSH协议可以有效防止远程管理过程中的信息泄露问题. import paramik ...

  8. Procedure-Function mysql

    1.基本用法 drop PROCEDURE if EXISTS sp1; -- 如果存在sp1存储过程则删除掉 create PROCEDURE sp1() SELECT 1; --创建最简单的存储过 ...

  9. Haskell语言学习笔记(36)Data.List.Zipper

    ListZipper 模块 $ cabal install ListZipper Installed ListZipper-1.2.0.2 Prelude> :m +Data.List.Zipp ...

  10. hibernate中.常见的hql查询语句

    hql是非常有意识的被设计为完全面向对象的查询 基本规则: 1.hql语法类似于sql,但它后面跟的不是表名和字段名,而是类名和属性名 2.hql大小写不敏感.但是设计java类名,包名,属性名时大小 ...