[关闭]
@Chiang 2020-10-02T11:40:03.000000Z 字数 3009 阅读 532

块作用域 函数作用域 闭包

2020-10 心得

PHP里面只有全局作用域和函数作用域,没有块作用域


php 之static静态变量详解

  • static 放在函数内部修饰变量
  1. // 在函数执行完后,变量值仍然保存
  2. function testStatic() {
  3. static $val = 1;
  4. echo $val;
  5. $val++;
  6. }
  7. testStatic(); //output 1
  8. testStatic(); //output 2
  9. testStatic(); //output 3
  • static放在类里修饰属性,或方法
  1. // 修饰属性或方法,可以通过类名访问,如果是修饰的是类的属性,保留值
  2. class Person {
  3. static $id = 0;
  4. function __construct() {
  5. self::$id++;
  6. }
  7. static function getId() {
  8. return self::$id;
  9. }
  10. }
  11. echo Person::$id; //output 0
  12. echo "<br/>";
  13. $p1=new Person();
  14. $p2=new Person();
  15. $p3=new Person();
  16. echo Person::$id; //output 3
  • static放在类的方法里修饰变量
  1. // 修饰类的方法里面的变量
  2. class Person {
  3. static function tellAge() {
  4. static $age = 0;
  5. $age++;
  6. echo "The age is: $age
  7. ";
  8. }
  9. }
  10. echo Person::tellAge(); //output 'The age is: 1'
  11. echo Person::tellAge(); //output 'The age is: 2'
  12. echo Person::tellAge(); //output 'The age is: 3'
  13. echo Person::tellAge(); //output 'The age is: 4'
  • static修饰在全局作用域的变量
  1. // 修饰全局作用域的变量,没有实际意义(存在着作用域的问题,详情查看)
  2. static $name = 1;
  3. $name++;
  4. echo $name;
  5. 另外:考虑到PHP变量作用域
  6. include 'ChromePhp.php';
  7. $age=0;
  8. $age++;
  9. function test1() {
  10. static $age = 100;
  11. $age++;
  12. ChromePhp::log($age); //output 101
  13. }
  14. function test2() {
  15. static $age = 1000;
  16. $age++;
  17. ChromePhp::log($age); //output 1001
  18. }
  19. test1();
  20. test2();
  21. ChromePhp::log($age); //outpuut 1
  • PHP里面只有全局作用域和函数作用域,没有块作用域
  1. include 'ChromePhp.php';
  2. $age = 0;
  3. $age++;
  4. for ($i=0; $i<10; $i++) {
  5. $age++;
  6. }
  7. ChromePhp::log($i); //output 10;
  8. ChromePhp::log($age); //output 11;

php 坑系列之块级作用域

  1. $arr = [1, 2, 4];
  2. foreach ($arr as $val) {
  3. $sum += $val;
  4. }
  5. var_dump($val,$sum);
  6. exit;
  7. // 输出
  8. int(4)
  9. int(7)

为什么foreach 循环内的sum变量已经退出循环了,打印出来还是显示变量存在?原因是:PHP有函数作用域,但是没有块级作用域,没有C/C++、java等语言的块级作用域概念,比如C++里面:

  1. //c++
  2. for(int i=0;i<10;i++){
  3. cout<<i<<endl;
  4. }
  5. i=11;//编译错误

因此,对于PHP以下几种情况变量都是存在的:

  1. for($i=0;$i<10;$i++){
  2. ;
  3. }
  4. var_dump($i);//输出int(10)
  5. // 不管隐藏几层循环还是一样
  6. for ($i = 0; $i < 10; $i++) {
  7. for ($j = 0; $j < 10; $j++) {
  8. $k = 777;
  9. }
  10. }
  11. var_dump($j);//输出10
  12. var_dump($k);//输出777

建议:每次使用变量前都初始化:

  1. for ($i = 0; $i < 10; $i++) {
  2. for ($j = 0; $j < 10; $j++) {
  3. $k = 777;
  4. }
  5. }
  6. $k = 0;//初始值,重新使用

那是不是初始化就万无一失了呢?看下面这个例子

  1. $arr = [1, 2, 4];
  2. foreach ($arr as &$val) {
  3. $val *= 2;
  4. }
  5. $val = [];//重新赋值
  6. $val[0]=9;
  7. $val[1]=10;
  8. var_dump($arr,$val);
  9. //输出结果
  10. array(3) {
  11. [0]=>
  12. int(2)
  13. [1]=>
  14. int(4)
  15. [2]=>
  16. &array(2) {
  17. [0]=>
  18. int(9)
  19. [1]=>
  20. int(10)
  21. }
  22. }
  23. array(2) {
  24. [0]=>
  25. int(9)
  26. [1]=>
  27. int(10)
  28. }

可以看到$arr数组的最后一个元素变成引用$val了。虽然重新赋值为空数组,但后面的修改还是会影响到了$arr。原因是$val是一个引用,后面的修改都会影响到,除非加unset($val);

  1. $arr = [1, 2, 4];
  2. foreach ($arr as &$val) {
  3. $val *= 2;
  4. }
  5. unset($val);
  6. $val = [];
  7. $val[0] = 9;
  8. $val[1] = 10;
  9. var_dump($arr, $val);
  10. // 输出结果:
  11. array(3) {
  12. [0]=>
  13. int(2)
  14. [1]=>
  15. int(4)
  16. [2]=>
  17. int(8)
  18. }
  19. array(2) {
  20. [0]=>
  21. int(9)
  22. [1]=>
  23. int(10)
  24. }

php 作用域

  • 作用域:变量能被访问到的区域 。php中的作用域与js中有所不同
  • js中函数内可以直接访问到全局变量,而在php中则无法直接访问
  • php变量的作用域可以分为三种

全局变量

简单理解,就是函数外部定义的变量,只能在函数外部进行访问

局部变量

其实就是函数内部定义的变量,只能在函数内部使用

超全局变量

系统定义的变量,包括的全部变量,任何地方都能访问
如何实现函数内部与函数外部的互相访问?
首先看一段代码,这样是无法运行的

  1. $a="123";
  2. function fun(){
  3. echo $a;
  4. }
  5. fun();

解决办法有三种:

  • 在函数中传入参数$a
  1. $a="123";
  2. function fun($a){
  3. echo $a;
  4. }
  5. fun($a);
  • 使用超全局变量$GLOBALS在函数内部进行访问
  1. $a="123";
  2. function fun(){
  3. echo $GLOBALS['a'];
  4. }
  5. fun();
  • 实现全局和局部的互相访问。使用Global关键字
  1. // 全局空间已存在变量,局部访问全局
  2. $a="123";
  3. function fun(){
  4. global $a;
  5. echo $a;
  6. }
  7. fun();
  8. // 全局空间不存在这个变量,全部访问局部
  9. function fun(){
  10. global $a;
  11. $a="123";
  12. }
  13. fun();
  14. echo $a;

php 匿名函数 use关键

php Arrow Functions

es5 函数

es6+ 函数的扩展


参考资料:
PHP之static静态变量详解
php坑系列之块级作用域
华子的程序人生
php 中use关键字的用法
匿名函数
Arrow Functions
ES5 函数
ES6+ 函数的扩展

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注