php 无法访问函数内部的全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5449526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:28:09  来源:igfitidea点击:

Can't access global variable inside function

phpvariablesscopeglobal-variables

提问by Camilo Martin

This (simplified version of my code) doesn't work:

这(我的代码的简化版本)不起作用:

<?php
    $sxml = new SimpleXMLElement('<somexml/>');

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

    foo();
?>

Why? I want to access $sxmlbecause I want to log errors on it if foo()fails. foo()calls itself recursively to create a directory listing, so I fear passing the whole $sxmlonto itself (as in foo($sxml)) could hurt performance.

为什么?我想访问,$sxml因为我想在foo()失败时记录错误。 foo()递归调用自身以创建目录列表,因此我担心将整个传递给$sxml自身(如foo($sxml))可能会损害性能。

Is there a way to access $sxmlinside $foowithout passing it as an argument? (PHP 5.2.x+)

有没有办法$sxml$foo不将其作为参数传递的情况下访问内部?(PHP 5.2.x+)

EDIT:What if the code looks like this, actually?

编辑:如果代码看起来像这样,实际上呢?

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

回答by Javi R

You have to pass it to the function:

您必须将其传递给函数:

<?php
    $sxml = new SimpleXMLElement('<somexml/>');

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

    foo($sxml);
?>

or declare it global:

或将其声明为全局

<?php
    $sxml = new SimpleXMLElement('<somexml/>');

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

    foo();
?>

If the variable isn't global but is instead defined in an outer function, the first option (passing as an argument) works just the same:

如果变量不是全局变量而是在外部函数中定义,则第一个选项(作为参数传递)的工作原理相同:

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

Alternatively, create a closureby declaring the variable in a useclause.

或者,通过在子句中声明变量来创建闭包use

<?php
    function bar() {
        $sxml = new SimpleXMLElement('<somexml/>');
        function foo() use(&$xml) {
            $child = $sxml->addChild('child');
        }
        foo();
    }
    bar();
?>

回答by mario

You need to explicitly invite the global variable into the functions scope:

您需要显式邀请全局变量进入函数范围:

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

回答by Shamim Hafiz

Use the global keyword to declare $sxml inside your function.

使用 global 关键字在您的函数中声明 $sxml。

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

回答by T.Todua

another solution is to use $GLOBALSwhile you declare that variable:

另一个解决方案是在声明该变量时使用$GLOBALS

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

回答by Matt Korostoff

While the top answer provides a nice solution, I'd like to argue that the appropriate solution in most modern PHP applications is to create a class with a static variable, like so:

虽然最佳答案提供了一个很好的解决方案,但我想争辩说,在大多数现代 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();

This approach allows you to access $sxmlfrom within foo()just like you wanted, but it has a few advantages over the globalapproach.

这种方法允许您按照自己的意愿$sxml从内部访问foo(),但与该global方法相比,它有一些优势。

  1. With this strategy, you will always be able to put a breakpoint inside setXML()to find out what part of your application has manipulated this value, which you cannot do when manipulating globals.
  2. You avoid polluting the global namespace with a generic variable name sxml.
  1. 使用此策略,您将始终能够在内部放置一个断点setXML()以找出应用程序的哪个部分操纵了该值,而在操纵全局变量时则无法做到这一点。
  2. 您可以避免使用通用变量名称污染全局命名空间sxml