【问题标题】:global variables in php not working as expectedphp中的全局变量没有按预期工作
【发布时间】:2025-12-17 10:25:01
【问题描述】:

我在 php 中遇到了全局变量的问题。我在一个文件中设置了一个$screen var,它需要另一个文件调用另一个文件中定义的initSession()initSession() 声明 global $screen,然后使用第一个脚本中设置的值进一步向下处理 $screen。

这怎么可能?

为了让事情更加混乱,如果您尝试再次设置 $screen 然后调用initSession(),它会再次使用第一次使用的值。以下代码将描述该过程。有人可以解释一下吗?

$screen = "list1.inc";            // From model.php
require "controller.php";         // From model.php
initSession();                    // From controller.php
global $screen;                   // From Include.Session.inc  
echo $screen; // prints "list1.inc" // From anywhere
$screen = "delete1.inc";          // From model2.php
require "controller2.php"         
initSession();
global $screen;
echo $screen; // prints "list1.inc" 

更新:
如果我在需要第二个模型之前再次声明 $screen 全局,则 $screen 会为 initSession() 方法正确更新。奇怪。

【问题讨论】:

  • global $a; 等价于$a =& $GLOBALS['a'];。也就是说,它在本地范围内创建一个同名的引用。在函数之外,您始终处于全局范围内。 PHP 不提供“文件范围”。

标签: php global


【解决方案1】:

Global 不会使变量成为全局变量。我知道这很棘手:-)

Global 表示将使用局部变量就好像它是具有更高范围的变量

E.G:

<?php

$var = "test"; // this is accessible in all the rest of the code, even an included one

function foo2()
{
    global $var;
    echo $var; // this print "test"
    $var = 'test2';
}

global $var; // this is totally useless, unless this file is included inside a class or function

function foo()
{
    echo $var; // this print nothing, you are using a local var
    $var = 'test3';
}

foo();
foo2();
echo $var;  // this will print 'test2'
?>

请注意,全局变量很少是一个好主意。如果没有模糊范围,您可以在 99.99999% 的时间内编写代码,并且您的代码更容易维护。如果可以,请避免使用global

【讨论】:

  • 我完全同意避免全局“如果可以的话”。这段代码是我们试图稍微扩展的框架的一部分,所以我们无法避免全局变量,因为我们没有把它们放在那里。
  • 对于课程来说是这样吗?
  • 不过,全局变量对于简单的脚本编写非常有用。特别是。如果你有配置并且 OO 不合适。
【解决方案2】:

global $foo 并不是说​​“让这个变量全局化,让每个人都可以使用它”。 global $foo 表示“在此函数范围内,使用全局变量$foo”。

我从您的示例中假设每次您都在函数中引用 $screen 。如果是这样,您将需要在每个函数中使用global $screen

【讨论】:

    【解决方案3】:

    您需要将“global $screen”放在引用它的每个函数中,而不仅仅是在每个文件的顶部。

    【讨论】:

      【解决方案4】:

      如果您想在使用许多函数的任务期间访问大量变量,请考虑创建一个“上下文”对象来保存这些内容:

      //We're doing "foo", and we need importantString and relevantObject to do it
      $fooContext = new StdClass(); //StdClass is an empty class
      $fooContext->importantString = "a very important string";
      $fooContext->relevantObject = new RelevantObject();
      
      doFoo($fooContext);
      

      现在只需将此对象作为参数传递给所有函数。您不需要全局变量,并且您的函数签名保持干净。以后也很容易将空的 StdClass 替换为实际上包含相关方法的类。

      【讨论】:

        【解决方案5】:

        全局范围跨越包含和必需的文件,除非在函数中使用变量,否则不需要使用 global 关键字。您可以尝试改用 $GLOBALS 数组。

        【讨论】:

          【解决方案6】:

          在为它定义值之前,您必须将变量声明为全局变量。

          【讨论】:

          • 您的答案对之前接受且高度支持的答案有何补充?愿意评论并添加一些示例代码吗?
          【解决方案7】:

          除非它在函数或类中,否则它是无用的。全局意味着您可以在程序的任何部分使用变量。因此,如果全局不包含在函数或类中,则使用 Global 是没有用的

          【讨论】: