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

ybzsozfc  于 2021-10-10  发布在  Java
关注(0)|答案(3)|浏览(321)

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

7uzetpgm

7uzetpgm1#

什么是“可变范围”?

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

如何在php中定义作用域?

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

例如:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}
``` `$foo` 在全球范围内,, `$baz` 在内部的局部范围内 `myFunc` . 里面只有代码 `myFunc` 有权访问 `$baz` . 只有外部代码 `myFunc` 有权访问 `$foo` . 任何一方都无法访问另一方:
nfzehxib

nfzehxib2#

虽然函数范围内定义的变量不能从外部访问,但这并不意味着在函数完成后不能使用它们的值。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 允许构建此简单计数器,无需其他解决方法。

静态变量用例

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

诡计

静态变量仅存在于局部函数作用域中。在已定义的函数之外无法访问它。因此,您可以确定,在下次调用该函数之前,它将保持其值不变。
静态变量只能定义为标量或标量表达式(从php 5.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概念,如“类常量”(如果它们通过值传递到闭包中)或“私有属性”(如果通过引用传递)。
后者实际上允许使用闭包而不是静态变量。使用什么总是由开发人员决定的,但应该提到的是,静态变量在处理递归时绝对有用,值得开发人员注意。

3duebb1j

3duebb1j3#

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

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

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

相关问题