访问 PHP 函数中的全局变量

Posted

技术标签:

【中文标题】访问 PHP 函数中的全局变量【英文标题】:Access a global variable in a PHP function 【发布时间】:2013-03-19 05:12:39 【问题描述】:

根据大多数编程语言的作用域规则,我可以访问在它们内部的函数之外定义的变量,但为什么这段代码不起作用?

<?php
    $data = 'My data';

    function menugen() 
        echo "[" . $data . "]";
    

    menugen();
?>

输出是[]

【问题讨论】:

不要将其视为全局,将其作为参数传递给函数 手册哪里有这样的说法? 相关阅读:PHP global in functions 查看本页的第二个例子:php.net/manual/en/language.variables.scope.php afaik 我们可以使用 $GLOBALS['varname'] 访问,其中索引“varname”是函数外的 $varname。事实上我们可以使用 print_r($GLOBALS) 查看所有全局变量。 【参考方案1】:

由于这个原因,PHP 可能会令人沮丧。上面使用global 的答案对我不起作用,我花了一段时间才弄清楚use 的正确用法。

这是正确的:

$functionName = function($stuff) use ($globalVar) 
 //do stuff

$output = $functionName($stuff);
$otherOutput = $functionName($otherStuff);

这是不正确的:

function functionName($stuff) use ($globalVar) 
 //do stuff

$output = functionName($stuff);
$otherOutput = functionName($otherStuff);

使用您的具体示例:

    $data = 'My data';

    $menugen = function() use ($data) 
        echo "[" . $data . "]";
    

    $menugen();

【讨论】:

【参考方案2】:

多年来我一直使用这种格式:

<?php
    $data = "Hello";

    function sayHello()
        echo $GLOBALS["data"];
    

    sayHello();
?>

我觉得它简单易懂。 $GLOBALS 是 PHP 让您引用全局变量的方式。如果您使用过 $_SERVER、$_POST 等,那么您在不知情的情况下引用了一个全局变量。

【讨论】:

哪一个? $GLOBAL(文本)还是$GLOBALS(示例代码)? (请通过editing your answer 回复,而不是在 cmets 中(视情况而定)。) 这是 $GLOBALS 而不是 $GLOBAL。应该有一个“S”。然后像关联数组的键一样引用您的变量名。 请update your answer by editing it(开始the editing,点击“edit”,在“share”之间flag"。这三个在左侧 - "edited""answered" 的左侧,在答案本身之后,在此评论上方,以及最重要的是这里的三个 cmets)。 cmets 中的信息随时可能消失。这不是论坛 - 信息可以(并且应该)在此处更新。非常感谢您。【参考方案3】:

另一种方法:

<?php

$data = 'My data';

$menugen = function() use ($data) 

    echo "[".$data."]";
;

$menugen();

2020-01-13 更新:彼得莫滕森要求

从 PHP 5.3.0 开始,我们支持可以创建闭包的匿名函数。闭包可以访问在其范围之外创建的变量。

在示例中,闭包能够访问$data,因为它是在use 子句中声明的。

【讨论】:

在我的案例中,这是唯一可行的解​​决方案,我将一个函数定义为另一个函数中的变量。 Global 在那里不起作用。 解释一下。例如,这个“使用”的东西是做什么的?这个“使用”的东西支持哪些 PHP 版本? (请通过editing your answer 回复,而不是在 cmets 中(视情况而定)。提前致谢。) 不知道为什么批准的 ans 在 Wordpress 管理插件页面中没有显示任何输出,但这个 ans 运行良好。【参考方案4】:
<?php

    $data = 'My data';

    $menugen = function() use ($data) 

        echo "[ $data ]";
    ;

    $menugen();
?>

你也可以简化

echo "[" . $data . "]"

echo "[$data]"

【讨论】:

echo "[" . $data . "]"echo "[ $data ]" 不一样(后者的输出中有两个额外的空格)。【参考方案5】:

您可以执行以下操作之一:

<?php
    $data = 'My data';

    function menugen() 
        global $data;
        echo "[" . $data . "]";
    

    menugen();

或者

<?php
    $data = 'My data';

    function menugen() 
        echo "[" . $GLOBALS['data'] . "]";
    

    menugen();

话虽如此,过度使用全局变量会导致一些糟糕的代码。通常最好传递你需要的东西。例如,您应该将一个句柄传递给数据库并对其进行操作,而不是引用一个全局数据库对象。这称为dependency injection。当您实施自动化测试(您应该这样做)时,它会让您的生活变得更轻松。

【讨论】:

【参考方案6】:

这是范围问题。总之,应该避免全局变量所以

您要么需要将其作为参数传递:

$data = 'My data';

function menugen($data)

    echo $data;

或者将它放在一个类中并访问它

class MyClass

    private $data = "";

    function menugen()
    
        echo this->data;
    


也请参阅@MatteoTassinari 答案,因为您可以将其标记为全局以访问它,但通常不需要全局变量,因此重新考虑您的编码是明智的。

【讨论】:

另一种方法是使用关键字global(当然,这不是最好的方法)。 “应该”没有回答这个问题,这可能不是每个案例的最佳方法。对于简单的脚本,更改参数和添加类是很麻烦的。与 javascript 非常相似,在 PHP 中,并非所有内容都需要面向对象并在 wazoo 中命名。 @Beejor 鉴于 OP 有一个名为 menugen() 的函数,这意味着将不仅仅是生成一个菜单。例如,如何扩展该菜单以添加来自不同来源的更多项目,如何选择菜单中当前选定的页面。到处都有随机的全局变量和逻辑,这对 OOP 设计来说是一种尖叫。 PHP / JS 不需要结构化这一事实是您发现大量杂乱笨拙代码的最大原因之一。它可以做得很好,但让人们不必考虑未来的可维护性。 它可能为隐含的问题提供了解决方案,但并没有真正回答原始问题,即如何访问函数中的全局变量。这就是人们通过网络搜索进入此页面的方式。 @Beejor - 这个论点的问题在于人们可能认为他们需要一个全局变量,因为他们不知道更好,除非他们知道被告知。【参考方案7】:

它不起作用,因为您必须声明您将访问哪些全局变量:

$data = 'My data';

function menugen() 
    global $data; // <-- Add this line

    echo "[" . $data . "]";


menugen();

否则,您可以使用$GLOBALS['data'] 访问它。请参阅Variable scope

即使有点离题,我建议您完全避免使用全局变量,而更喜欢作为参数传递。

【讨论】:

谢谢,你是对的,但他们没有在手册的第二个例子中使用这一行:php.net/manual/en/language.variables.scope.php 事实上,第二个例子是为了向读者展示该做什么:This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope. 该死!我必须登录才能投票赞成这个答案,因为我令人毛骨悚然地忘记了 php 变量范围。【参考方案8】:

你需要将变量传递给函数:

$data = 'My data';

function menugen($data)

    echo $data;

【讨论】:

以上是关于访问 PHP 函数中的全局变量的主要内容,如果未能解决你的问题,请参考以下文章

php变量等入门

PHP 全局变量 - 超全局变量

PHP 全局变量 - 超全局变量

PHP 全局变量 - 超全局变量

PHP 5 全局变量 - 超全局变量

PHP-作用域相关