reference:什么是变量范围,哪些变量可以从何处访问,哪些是“未定义变量”错误?

2mbi3lxu  于 2021-06-25  发布在  Mysql
关注(0)|答案(3)|浏览(480)

注意:这是一个在php中处理变量作用域的参考问题。请将符合此模式的许多问题中的任何一个作为此问题的副本关闭。
什么是php中的“变量范围”?一个.php文件中的变量可以在另一个文件中访问吗?为什么有时会出现“未定义变量”错误?

xuo3flqw

xuo3flqw1#

什么是“可变范围”?

变量的“作用域”或“可访问的位置”是有限的。就因为你写了 $foo = 'bar'; 在你的应用程序中的某个地方,并不意味着你可以引用 $foo 从应用程序中的其他任何地方。变量 $foo 在某个范围内有效,并且只有同一范围内的代码才能访问该变量。

如何在php中定义作用域?

非常简单:php有函数作用域。这是php中唯一存在的范围分隔符。函数中的变量仅在该函数中可用。函数外的变量在函数外的任何地方都可用,但在任何函数内都不可用。这意味着php中有一个特殊的作用域:全局作用域。在任何函数之外声明的任何变量都在此全局范围内。

示例:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}
``` `$foo` 在全球范围内, `$baz` 在内部的本地范围内 `myFunc` . 只有代码在里面 `myFunc` 有权访问 `$baz` . 只有代码在外面 `myFunc` 有权访问 `$foo` . 两者都不能接触对方:
l0oc07j2

l0oc07j22#

对于这个问题,我不会给出一个完整的答案,因为现有的答案和php手册都很好地解释了其中的大部分内容。
但有一个被遗漏的主题是超球体,包括常用的 $_POST , $_GET , $_SESSION 这些变量是数组,在任何范围内都是可用的,没有 global 宣言。
例如,此函数将打印出运行php脚本的用户的名称。变量对函数可用,没有任何问题。

<?php
function test() {
    echo $_ENV["user"];
}

“globals是坏的”的一般规则在php中通常被修改为“globals是坏的,但是superglobals是好的”,只要不误用它们(所有这些变量都是可写的,所以如果你真的很糟糕的话,可以用它们来避免依赖注入。)
这些变量不能保证存在;管理员可以使用 variables_order 中的指令 php.ini ,但这不是常见的行为。
当前超全局的列表: $GLOBALS -当前脚本中的所有全局变量 $_SERVER -有关服务器和执行环境的信息 $_GET -在url的查询字符串中传递的值,而不考虑用于请求的http方法 $_POST -在http post请求中传递的值 application/x-www-form-urlencoded 或者 multipart/form-data mime类型 $_FILES -在http post请求中传递的文件 multipart/form-data mime类型 $_COOKIE -与当前请求一起传递的Cookie $_SESSION -php内部存储的会话变量 $_REQUEST -通常是 $_GET 以及 $_POST ,但有时 $_COOKIES . 含量取决于 request_order 中的指令 php.ini . $_ENV -当前脚本的环境变量

368yc8dk

368yc8dk3#

虽然不能从外部访问在函数作用域内定义的变量,但这并不意味着在函数完成后不能使用它们的值。php有一个众所周知的 static 在面向对象的php中被广泛用于定义静态方法和属性的关键字,但是应该记住 static 也可以在函数中用于定义静态变量。

什么是“静态变量”?

静态变量不同于在函数作用域中定义的普通变量,因为当程序执行离开这个作用域时,它不会丢失值。让我们考虑以下使用静态变量的示例:

function countSheep($num) {
 static $counter = 0;
 $counter += $num;
 echo "$counter sheep jumped over fence";
}

countSheep(1);
countSheep(2);
countSheep(3);

结果:

1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence

如果我们定义了 $counter 没有 static 那么每一次的回声值都是相同的 $num 传递给函数的参数。使用 static 允许构建此简单计数器而无需其他解决方法。

静态变量用例

在函数的后续调用之间存储值。
当无法(或没有目的)将值作为参数传递时,在递归调用之间存储值。
缓存通常最好检索一次的值。例如,读取服务器上不可变文件的结果。

诡计

静态变量只存在于局部函数作用域中。不能在已定义的函数之外访问它。因此,您可以确定它将保持其值不变,直到下一次调用该函数为止。
静态变量只能定义为标量或标量表达式(从PHP5.6开始)。给它赋值不可避免地会导致失败,至少在撰写本文时是这样。不过,您可以在代码的下一行执行此操作:

function countSheep($num) {
  static $counter = 0;
  $counter += sqrt($num);//imagine we need to take root of our sheep each time
  echo "$counter sheep jumped over fence";
}

结果:

2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence

静态函数在同一类的对象的方法之间是“共享”的。通过查看以下示例很容易理解:

class SomeClass {
  public function foo() {
    static $x = 0;
    echo ++$x;
  }
}

$object1 = new SomeClass;
$object2 = new SomeClass;

$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother

这只适用于同一类的对象。如果对象来自不同的类(甚至彼此扩展),静态变量的行为将如预期的那样。

静态变量是在函数调用之间保持值的唯一方法吗?

另一种在函数调用之间保持值的方法是使用闭包。闭包是在PHP5.3中引入的。换句话说,它们允许您将对某个函数范围内某组变量的访问限制为另一个匿名函数,这是访问这些变量的唯一方法。处于闭包变量中可能会模仿(或多或少成功地)oop概念,如结构化编程中的“类常量”(如果通过值在闭包中传递)或“私有属性”(如果通过引用传递)。
后者实际上允许使用闭包而不是静态变量。使用什么总是由开发人员决定的,但应该提到的是,静态变量在处理递归时绝对有用,值得开发人员注意。

相关问题