2010-12-07 47 views
2

Lors de la transmission d'une valeur inexistante par référence, PHP crée la valeur et la définit sur NULL. Je l'ai remarqué quand des augmentations de mémoire se produisaient en vérifiant des valeurs vides dans certaines fonctions. Prenez la fonction suivante:L'utilisation de la référence à des valeurs inexistantes définit une variable sur NULL?

function v(&$v,$d=NULL){return isset($v)?$v:$d;} 
$bar = v($foo, $default); 

Ce serait un raccourci pour:

if(isset($foo)) 
{ 
    $bar = $foo; 
} 
else 
{ 
    $bar = $default; 
} 

Cependant, lors du passage des variables non existantes PHP les crée. Dans le cas de variables - elles sont supprimées dès que la méthode/fonction se termine - mais pour vérifier des tableaux super globaux comme $ _GET ou $ _POST, l'élément de tableau n'est jamais supprimé, ce qui augmente l'utilisation de la mémoire.

$request_with = v($_SERVER['HTTP_X_REQUESTED_WITH']); 

Quelqu'un peut-il expliquer pourquoi cela se produit et si elle est une solution de todo PHP ou une fonction pour une autre utilisation fou de valeurs?

+0

Quel est l'environnement de votre serveur? – RobertPitt

+0

PHP 5.3.x sur Debian, Ubuntu et Windows XP exécutant PHPFastcgi. – Xeoncross

Répondre

2

La raison pour laquelle vous avez une fuite de mémoire est que vous le lui dites.

Lorsque vous demandez un paramètre de référence, PHP vous en fournira un. Lorsque vous appelez une fonction avec une variable non définie, PHP va définir la variable, puis transmettre la référence à cette nouvelle variable. Lorsque vous l'appelez avec un superglobal, il crée l'index manquant. C'est parce que tu l'as dit.

Cependant, je dois vous demander pourquoi avez-vous spécifiquement besoin de références variables? 99,9% du temps, vous n'avez pas vraiment besoin d'eux. Je pense que ça va marcher très bien faire:

function v($v, $d = null) { return isset($v) ? $v : $d; } 

Ou, si vous devez vraiment utiliser des références (que vous ne pouvez pas contourner votre problème d'origine avec), vous devez également retourner une référence:

function &v(&$v, $d = null) { 
    if (isset($v)) { 
     return $v; 
    } 
    return $d; 
} 

Sinon, il est inutile de prendre une référence et non un retour ...

+0

Pointless en effet. Ma seule supposition est qu'il pense qu'il économise des ressources en ne passant pas en valeur. Malheureusement, il n'est pas au courant de COW (copy-on-write). – webbiedave

+0

Je suis au courant de COW, économiser de la mémoire n'est pas le point de la fonction. Traiter des valeurs inexistantes est. cependant, 'function & v() {...}' n'est pas valide PHP: 'Remarque: Seules les références de variables doivent être renvoyées par référence', c'est pourquoi il est écrit comme il est. En d'autres termes, les références sont le seul moyen de gérer les valeurs non définies sans provoquer d'erreur de PHP. – Xeoncross

2

fonction XeonCross v est un raccourci pour le souvent utilisé:

$val= isset($arr['elm']) ? $arr['elm'] : 'default' 

pour éviter l'avis redouté 'Indéfini index: elm'. Une belle fonction d'aide serait:

function ifset(&$v1, $v2 = null) { 
    return isset($v1) ? $v1 : $v2; 
} 

comme le suggère Xeoncross, vous pouvez donc écrire le plus agréable

$val = ifset($arr['elm'],'default') 

cependant, cela a beaucoup d'intéressantes bizarreries dans notre bien-aimé « la langue » (?) que nous appelons PHP:

à l'intérieur de la fonction ifset, $ v1 semble UNSET, donc il renvoie correctement la valeur $ v2 et vous pouvez conclure que ifset fonctionne bien. Mais ensuite $ arr ['elm'] est silencieusement défini sur NULL. Regarde donc ce qui suit:

function wtf(&$v) { 
     if (isset($v)) 
      echo "It is set"; 
     else 
      echo "It is NOT set"; 
    } 
    $p=[]; 
    wtf($p['notexist']); => It is NOT set 
    $p;     => [ 'notexist' => NULL ] 

Mais ceci est une autre illusion, comme la fonction isset retourne false() pour les valeurs NULL ainsi:

$x=NULL; 
isset($x) => false... huh?? 

Avons-nous attendons à ce que? Eh bien .. il est dans la documentation, donc c'est par conception aussi bien.Bienvenue dans le monde merveilleux de php.

+0

J'ai aussi créé une méthode exactement comme celle-ci. Et puis j'ai perdu la moitié de la journée à essayer de comprendre ce qui crée des données merdiques dans mes tableaux. : / – morgoth84