2011-03-27 159 views
46

这(简化我的代码版本)不工作:无法访问全局变量内部功能

<?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(); 
?> 
+0

请,做OOP或者只是把它作为参数。可重用性是关键。 – mauris 2011-03-27 13:40:42

+0

@thephpdeveloper我明白你的意思,但我刚刚开始使用PHP,这可能不是我将重用的代码。这更像是一个原型,如果出现错误,我可以扔掉并从头开始。 – 2011-03-27 13:47:25

回答

97

你必须把它传递给函数:

<?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(); 
?> 
+0

还有一件事......如果变量在父函数中呢? (编辑问题):( – 2011-03-27 13:57:01

+0

)在你的第二个例子中,你不能访问foo()中的$ sxml,因为它是在bar()中本地定义的,解决方案可能是:在foo()和bar()外声明$ sxml,使用它在两个函数使用全球。但作为PHP开发者建议,你应该使用OOP;) – 2011-03-27 14:19:06

+0

我会使用OOP然后...我想快速和脏意味着损坏:( – 2011-03-27 14:38:22

19

你需要明确邀请全局变量到功能范围:

function foo(){ 
    global $sxml; 
    $child = $sxml->addChild('child'); 
} 
4

使用全球关键字来声明自己的函数中$ sxml。

<?php 
    $sxml = new SimpleXMLElement('<somexml/>'); 
    function foo(){ 
    global $sxml; 
    $child = $sxml->addChild('child'); 
    } 
    foo(); 
?> 
2

另一种解决方案是当你声明变量使用$ GLOBALS

  $my_var = 'blabla'; // not global 
$GLOBALS['my_var'] = 'blabla'; // global (correct)