94

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

<?php
    $data = 'My data';

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

    menugen();
?>

输出是[]

4

8 回答 8

178

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

$data = 'My data';

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

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

menugen();

否则,您可以将其作为$GLOBALS['data']. 请参阅变量范围

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

于 2013-03-28T16:38:58.500 回答
22

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

<?php
    $data = 'My data';

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

    menugen();

或者

<?php
    $data = 'My data';

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

    menugen();

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

于 2013-03-28T16:42:03.640 回答
16

另一种方法:

<?php

$data = 'My data';

$menugen = function() use ($data) {

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

$menugen();

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

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

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

于 2016-02-05T20:32:47.357 回答
12

这是范围的问题。简而言之,应该避免使用全局变量

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

$data = 'My data';

function menugen($data)
{
    echo $data;
}

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

class MyClass
{
    private $data = "";

    function menugen()
    {
        echo this->data;
    }

}

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

于 2013-03-28T16:40:20.683 回答
5

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

<?php
    $data = "Hello";

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

    sayHello();
?>

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

于 2019-08-27T03:07:44.570 回答
0
<?php

    $data = 'My data';

    $menugen = function() use ($data) {

        echo "[ $data ]";
    };

    $menugen();
?>

你也可以简化

echo "[" . $data . "]"

echo "[$data]"
于 2019-11-21T02:18:53.713 回答
0

由于这个原因,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();
于 2020-11-27T20:25:45.690 回答
-2

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

$data = 'My data';

function menugen($data)
{
    echo $data;
}
于 2013-03-28T16:38:29.800 回答