php 函数中静态变量使用的问题实例分析

本文实例讲述了php 函数中静态变量使用的问题,分享给大家供大家参考,具体如下:

  1. <?php
  2. function msg() {
  3. static $a = 0;
  4. echo $a++, '<br />';
  5. }
  6. msg();
  7. msg();
  8. msg();

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

当第二次调用msg()函数时,这时的$a值为1,而不会变成0。

那么问题来了,请看下面的一段代码:

  1. $data = array(
  2. array('id' => 1, 'title' => '衣服', 'parent' => 0),
  3. array('id' => 2, 'title' => '鞋子', 'parent' => 0),
  4. array('id' => 3, 'title' => '衬衫', 'parent' => 1),
  5. array('id' => 4, 'title' => 'T恤', 'parent' => 1),
  6. array('id' => 5, 'title' => '运动鞋', 'parent' => 2),
  7. array('id' => 6, 'title' => '休闲鞋', 'parent' => 2),
  8. );
  9. $data2 = array(
  10. array('id' => 1, 'title' => '食物', 'parent' => 0),
  11. array('id' => 2, 'title' => '肉食', 'parent' => 1),
  12. array('id' => 3, 'title' => '素食', 'parent' => 1),
  13. array('id' => 4, 'title' => '牛肉', 'parent' => 2),
  14. array('id' => 5, 'title' => '面条', 'parent' => 3),
  15. array('id' => 6, 'title' => '馒头', 'parent' => 3),
  16. );
  17. //生成树型数据
  18. function genTree($items, $id = 'id', $pid = 'parent', $son = 'child') {
  19. $tree = array();
  20. $tmpMap = array();
  21. foreach ($items as $item) {
  22. $tmpMap[$item[$id]] = $item;
  23. }
  24. foreach ($items as $item) {
  25. if (isset($tmpMap[$item[$pid]])) {
  26. $tmpMap[$item[$pid]][$son][] = &$tmpMap[$item[$id]];
  27. } else {
  28. $tree[] = &$tmpMap[$item[$id]];
  29. }
  30. }
  31. unset($tmpMap);
  32. return $tree;
  33. }
  34. //通过给定数据,返回option的字符串,用于select下拉框
  35. function getOpts($data, $idArr = array(), $level = 0, $son = 'child') {
  36. static $opt = '';
  37. if (!emptyempty($data)) {
  38. foreach ($data as $k => $v) {
  39. $opt .= '<option value=' . $v['id'] . (in_array($v['id'], $idArr) ? ' selected="true"' : '') . '>' . str_repeat(' ', $level * 3) . $v['title'] . '</option>';
  40. if (!emptyempty($v[$son])) {
  41. getOpts($v[$son], $idArr, $level + 1, $son);
  42. }
  43. }
  44. }
  45. return $opt;
  46. }
  47. $data = genTree($data);
  48. echo '<select>';
  49. //第一次调用getOpts时,没有任何问题。
  50. echo getOpts($data);
  51. echo '</select>';
  52. $data2 = genTree($data2);
  53. echo '<select>';
  54. //当第二次调用时,问题就出现了,还留有上次的数据
  55. echo getOpts($data2);
  56. echo '</select>';

上述问题,对于可能多次调用的函数,不建议在内部使用静态变量。

修改getOpts函数如下,从函数参数引入一个外部变量的引用,来解决此问题。

  1. function getOpts($data, $idArr = array(), &$opt = '', $level = 0, $son = 'child') {
  2. if (!emptyempty($data)) {
  3. foreach ($data as $k => $v) {
  4. $opt .= '<option value=' . $v['id'] . (in_array($v['id'], $idArr) ? ' selected="true"' : '') . '>' . str_repeat(' ', $level * 3) . $v['title'] . '</option>';
  5. if (!emptyempty($v[$son])) {
  6. getOpts($v[$son], $idArr, $opt, $level + 1, $son);
  7. }
  8. }
  9. }
  10. }
  11. $data = genTree($data);
  12. getOpts($data, array(), $opt);
  13. echo '<select>';
  14. echo $opt;
  15. echo '</select>';
  16. $data2 = genTree($data2);
  17. getOpts($data2, array(), $opt2);
  18. echo '<select>';
  19. echo $opt2;
  20. echo '</select>';