无法访问函数内部的全局变量
Posted
技术标签:
【中文标题】无法访问函数内部的全局变量【英文标题】:Can't access global variable inside function 【发布时间】:2011-07-23 21:36:30 【问题描述】:这(我的代码的简化版本)不起作用:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo()
$child = $sxml->addChild('child');
foo();
?>
为什么?我想访问$sxml
,因为如果foo()
失败,我想在上面记录错误。 foo()
递归调用自身以创建目录列表,所以我担心将整个 $sxml
传递给自身(如在 foo($sxml)
中)可能会损害性能。
有没有办法访问$foo
内部的$sxml
而无需将其作为参数传递? (PHP 5.2.x+)
编辑:如果代码实际上是这样的呢?
<?php
bar()
$sxml = new SimpleXMLElement('<somexml/>');
function foo()
$child = $sxml->addChild('child');
foo();
bar();
?>
【问题讨论】:
请执行 OOP 或将其作为参数传递。可重用性是关键。 @thephpdeveloper 我理解你的意思,但我刚刚开始使用 PHP,这可能不是我将重用的代码。它更像是一个原型,如果出现问题,我可以扔掉并从头开始。 【参考方案1】:你必须将它传递给函数:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo($sxml)
$child = $sxml->addChild('child');
foo($sxml);
?>
或声明global:
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo()
global $sxml;
$child = $sxml->addChild('child');
foo();
?>
如果变量不是全局变量而是在外部函数中定义的,第一个选项(作为参数传递)的作用相同:
<?php
function bar()
$sxml = new SimpleXMLElement('<somexml/>');
function foo($sxml)
$child = $sxml->addChild('child');
foo($sxml);
bar();
?>
或者,通过在use
子句中声明变量来创建closure。
<?php
function bar()
$sxml = new SimpleXMLElement('<somexml/>');
function foo() use(&$xml)
$child = $sxml->addChild('child');
foo();
bar();
?>
【讨论】:
还有一件事......如果变量在父函数中怎么办? (问题已编辑):( 在第二个示例中,您无法从 foo() 访问 $sxml,因为它是在 bar() 中本地定义的。一个解决方案可能是:在 foo() 和 bar() 之外声明 $sxml,并在两个函数中使用 global。但正如 phpdeveloper 所建议的,你应该使用 OOP ;)【参考方案2】:您需要显式邀请全局变量进入函数范围:
function foo()
global $sxml;
$child = $sxml->addChild('child');
【讨论】:
【参考方案3】:使用 global 关键字在函数中声明 $sxml。
<?php
$sxml = new SimpleXMLElement('<somexml/>');
function foo()
global $sxml;
$child = $sxml->addChild('child');
foo();
?>
【讨论】:
【参考方案4】:另一种解决方案是在声明该变量时使用 $GLOBALS:
$my_var = 'blabla'; // not global
$GLOBALS['my_var'] = 'blabla'; // global (correct)
【讨论】:
【参考方案5】:虽然上面的答案提供了一个很好的解决方案,但我想说的是,在大多数现代 PHP 应用程序中,适当的解决方案是创建一个带有静态变量的类,如下所示:
<?php
class xmlHelper
private static $sxml;
public function getXML()
return self::$sxml;
public function setXML($xml)
self::$sxml = $xml;
xmlHelper::setXML(new SimpleXMLElement('<somexml/>'));
function foo()
$child = xmlHelper::getXML()->addChild('child');
foo();
这种方法允许您从foo()
中访问$sxml
,就像您想要的那样,但它比global
方法有一些优势。
-
使用此策略,您将始终能够在
setXML()
中放置一个断点,以找出您的应用程序的哪个部分操纵了该值,而在操纵全局变量时您无法做到这一点。
避免使用通用变量名称 sxml
污染全局命名空间。
【讨论】:
以上是关于无法访问函数内部的全局变量的主要内容,如果未能解决你的问题,请参考以下文章