访问 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 函数中的全局变量的主要内容,如果未能解决你的问题,请参考以下文章