web-dev-qa-db-fra.com

Impossible d'accéder à la variable globale à l'intérieur de la fonction

Cette (version simplifiée de mon code) ne fonctionne pas:

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

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

    foo();
?>

Pourquoi? Je veux accéder à $sxml Parce que je veux y enregistrer des erreurs si foo() échoue. foo() s'appelle récursivement pour créer une liste de répertoires, donc je crains que le passage de $sxml sur lui-même (comme dans foo($sxml)) pourrait nuire aux performances.

Existe-t-il un moyen d'accéder à $sxml À l'intérieur de $foo Sans le passer en argument? (PHP 5.2.x +)

EDIT: Et si le code ressemble à ceci, en fait?

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

Vous devez le passer à la fonction:

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

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

    foo($sxml);
?>

ou le déclarer global :

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

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

    foo();
?>

Si la variable n'est pas globale mais est définie à la place dans une fonction externe, la première option (passant comme argument) fonctionne de la même manière:

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

Sinon, créez un fermeture en déclarant la variable dans une clause use.

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

Vous devez inviter explicitement la variable globale dans la portée des fonctions:

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

Utilisez le mot-clé global pour déclarer $ sxml dans votre fonction.

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

une autre solution consiste à utiliser $ GLOBALS pendant que vous déclarez cette variable:

         $my_var   = 'blabla';    // not global
$GLOBALS['my_var'] = 'blabla';    // global  (correct)
4
T.Todua

Alors que la première réponse fournit une bonne solution, je voudrais faire valoir que la solution appropriée dans la plupart des applications PHP PHP consiste à créer une classe avec une variable statique, comme ceci:

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

Cette approche vous permet d'accéder à $sxml Depuis foo() comme vous le vouliez, mais elle présente quelques avantages par rapport à l'approche global.

  1. Avec cette stratégie, vous pourrez toujours mettre un point d'arrêt à l'intérieur de setXML() pour découvrir quelle partie de votre application a manipulé cette valeur, ce que vous ne pouvez pas faire lors de la manipulation de globaux.
  2. Vous évitez de polluer l'espace de noms global avec un nom de variable générique sxml.
3
Matt Korostoff