Comment obtenir un nom de variable sous forme de chaîne en PHP?

201

Disons que j'ai ce code PHP:

$FooBar = "a string";

j'ai alors besoin d'une fonction comme celle-ci:

print_var_name($FooBar);

qui imprime:

FooBar

Des idées comment y parvenir? Est-ce même possible en PHP?

Gary Willoughby
la source
9
Si vous en avez besoin pour autre chose que le débogage, vous faites quelque chose de grave. Quel est votre cas d'utilisation?
troelskn
10
Bonne question. J'avais besoin de la même chose pour le débogage.
prend
17
+1 - J'en avais besoin pour générer automatiquement une réponse XML ou JSON à partir d'un objet PHP modèle. Le fait d'envelopper l'objet dans un autre rootName => modelObjecttableau nommé ajoute simplement une profondeur inutile à la réponse. Je souhaite que cela soit intégré dans les capacités de réflexion d'exécution du langage.
Anurag
4
J'avais également besoin de cela dans une fonction de journalisation. Je voulais pouvoir faire ce qui suit: log ($ didTheSystemBlowUp); Pour apparaître dans le fichier journal comme: $ didTheSystemBlowUp = 'pas encore, mais très bientôt';
SeanDowney
4
Cela peut également être utile lors de l'appel de var_dump (), donc lorsque vous appelez en même temps sur plusieurs variables, vous n'avez pas sorti manuellement le nom var pour distinguer les sorties de vardupms.
PHPst

Réponses:

37

Vous pouvez utiliser get_defined_vars () pour trouver le nom d'une variable qui a la même valeur que celle dont vous essayez de trouver le nom. Évidemment, cela ne fonctionnera pas toujours, car différentes variables ont souvent les mêmes valeurs, mais c'est la seule façon de penser à cela.

Edit: get_defined_vars () ne semble pas fonctionner correctement, il retourne 'var' car $ var est utilisé dans la fonction elle-même. $ GLOBALS semble fonctionner, donc je l'ai changé pour ça.

function print_var_name($var) {
    foreach($GLOBALS as $var_name => $value) {
        if ($value === $var) {
            return $var_name;
        }
    }

    return false;
}

Edit: pour être clair, il n'y a pas de bon moyen de le faire en PHP, probablement parce que vous ne devriez pas avoir à le faire. Il existe probablement de meilleures façons de faire ce que vous essayez de faire.

Jeremy Ruten
la source
2
Ahh. Été trop lent ;-) Pensé la même chose, mais en utilisant $ GLOBALS à la place. Ainsi, la comparaison d'identité donne la vérité pour des valeurs scalaires égales ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel
En fait, maintenant que j'ai testé mon code, mon code renvoyait toujours 'var' car il était utilisé dans la fonction. Lorsque j'utilise $ GLOBALS à la place, il renvoie le nom de variable correct pour une raison quelconque. Je vais donc changer le code ci-dessus pour utiliser $ GLOBALS.
Jeremy Ruten
Ouais, j'ai réalisé mais get_defined_vars () était assez ta.
Gary Willoughby
2
Il existe de nombreux cas où ce code ne se comportera pas comme prévu.
troelskn
122
Ce code est HORRIBLEMENT incorrect. Vérifier que f la variable est la même que celle envoyée par VALUE est une idée très stupide. Des myriades de variables sont NULL à tout moment donné. Les myriades sont définies sur 1. C'est tout simplement fou.
Alex Weinstein
49

Je ne pouvais pas non plus penser à un moyen de le faire efficacement, mais j'ai trouvé cela. Cela fonctionne, pour les utilisations limitées ci-dessous.

hausser les épaules

<?php

function varName( $v ) {
    $trace = debug_backtrace();
    $vLine = file( __FILE__ );
    $fLine = $vLine[ $trace[0]['line'] - 1 ];
    preg_match( "#\\$(\w+)#", $fLine, $match );
    print_r( $match );
}

$foo = "knight";
$bar = array( 1, 2, 3 );
$baz = 12345;

varName( $foo );
varName( $bar );
varName( $baz );

?>

// Returns
Array
(
    [0] => $foo
    [1] => foo
)
Array
(
    [0] => $bar
    [1] => bar
)
Array
(
    [0] => $baz
    [1] => baz
)

Il fonctionne sur la base de la ligne qui a appelé la fonction, où il trouve l'argument que vous avez transmis. Je suppose qu'il pourrait être étendu pour fonctionner avec plusieurs arguments mais, comme d'autres l'ont dit, si vous pouviez mieux expliquer la situation, une autre solution serait probablement mieux travailler.

Nick Presta
la source
2
Cela fonctionne, mais uniquement si la fonction varName est définie dans le même fichier que la variable à trouver.
rubo77
1
Ici, vous trouverez une meilleure implémentation qui fonctionne sur plusieurs inclus: stackoverflow.com/a/19788805/1069083
rubo77
31

Vous pourriez envisager de changer votre approche et d'utiliser un nom de variable variable?

$var_name = "FooBar";
$$var_name = "a string";

alors vous pourriez juste

print($var_name);

obtenir

FooBar

Voici le lien vers le manuel PHP sur les variables variables


la source
42
J'ai travaillé avec un système qui utilisait largement des variables variables. Permettez-moi de vous avertir, ça sent vraiment mauvais très vite!
Icode4food
3
la plupart des cas, l'utilisateur souhaite obtenir le nom et la valeur d'une var. pensez "function debugvar ($ varname)" et il a l'intention de l'appeler "debugvar ('foo')" afin que le débogage affiche "foo = 123". avec variable variable, ils obtiendront «foo» n'est pas défini.
gcb
regardez ce que vous faites réellement. Là, dans votre exemple, vous CRÉEZ réellement une variable $FooBaravec la valeur qu'il vous a stringsuffit de lire votre manuel. C'est horrible à mon humble avis. vous n'attribuez jamais de $FooBarvaleur à la variable , mais elle est là. OUCH
Toskan
20

Personne ne semble avoir mentionné les raisons fondamentales pour lesquelles cela est a) difficile et b) imprudent:

  • Une "variable" n'est qu'un symbole pointant vers autre chose. En PHP, il pointe en interne vers quelque chose appelé "zval", qui peut en fait être utilisé pour plusieurs variables simultanément, soit parce qu'elles ont la même valeur (PHP implémente quelque chose appelé "copie sur écriture" de sorte qu'il $foo = $barn'a pas besoin de allouer de la mémoire supplémentaire immédiatement) ou parce qu’elles ont été attribuées (ou passées à une fonction) par référence (par exemple $foo =& $bar). Un zval n'a donc pas de nom.
  • Lorsque vous passez un paramètre à une fonction, vous créez une nouvelle variable (même s'il s'agit d'une référence). Vous pouvez passer quelque chose d'anonyme, comme "hello", mais une fois dans votre fonction, c'est la variable que vous nommez. Ceci est assez fondamental à la séparation de code: si une fonction reposait sur ce qu'est une variable utilisée pour appeler, il serait plus comme une gotoqu'une fonction bien distincte.
  • Les variables globales sont généralement considérées comme une mauvaise idée. De nombreux exemples ici supposent que la variable dans laquelle vous souhaitez "refléter" peut être trouvée $GLOBALS, mais cela ne sera vrai que si vous avez mal structuré votre code et que les variables ne sont pas limitées à une fonction ou un objet.
  • Les noms de variables sont là pour aider les programmeurs à lire leur code. Renommer des variables pour mieux répondre à leur objectif est une pratique de refactorisation très courante, et le fait est que cela ne fait aucune différence.

Maintenant, je comprends le désir de cela pour le débogage (bien que certaines des utilisations proposées vont bien au-delà), mais en tant que solution généralisée, ce n'est pas vraiment aussi utile que vous pourriez le penser: si votre fonction de débogage dit que votre variable est appelée "$ file ", il peut s'agir de l'une des dizaines de variables" $ file "de votre code, ou d'une variable que vous avez appelée" $ filename "mais que vous passez à une fonction dont le paramètre est appelé" $ file ".

Une information beaucoup plus utile est d'où dans votre code la fonction de débogage a été appelée. Étant donné que vous pouvez trouver rapidement cela dans votre éditeur, vous pouvez voir quelle variable vous sortiez pour vous-même, et pouvez même y passer des expressions entières en une seule fois (par exempledebug('$foo + $bar = ' . ($foo + $bar)) ).

Pour cela, vous pouvez utiliser cet extrait en haut de votre fonction de débogage:

$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];
IMSoP
la source
Il y a déjà de bonnes réponses. Donc, c'est juste être pessimiste même face à la réalité.
a20
@ a20 Toutes les réponses comportent de lourdes mises en garde quant au moment où elles peuvent être utilisées et quand elles se briseront; aucune n'est une simple recherche d'une variable à son nom, car c'est en fait impossible. Certains font beaucoup de réflexion géniale à des fins de débogage, ce qui est bien; Cependant, mon opinion est que vous feriez mieux de simplement sortir le numéro de ligne et de rechercher la ligne de source vous-même - ou d'utiliser un débogueur interactif comme XDebug.
IMSoP
14

C'est exactement ce que vous voulez - c'est une fonction "copier-déposer" prête à l'emploi qui fait écho au nom d'un var donné:

function print_var_name(){
    // read backtrace
    $bt   = debug_backtrace();
    // read file
    $file = file($bt[0]['file']);
    // select exact print_var_name($varname) line
    $src  = $file[$bt[0]['line']-1];
    // search pattern
    $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
    // extract $varname from match no 2
    $var  = preg_replace($pat, '$2', $src);
    // print to browser
    echo trim($var);
}

USAGE: print_var_name ($ FooBar)

IMPRESSION: FooBar

ASTUCE Maintenant, vous pouvez renommer la fonction et elle fonctionnera toujours et utilisera également la fonction plusieurs fois sur une seule ligne! Merci à @Cliffordlife

adilbo
la source
3
Cool, merci pour cela. J'ai légèrement modifié la ligne $ pat de $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';cette façon, peu m'importe comment cette fonction de débogage est appelée, et j'obtiens exactement ce qui est passé dans la fonction, c'est-à-dire $ bonjour ou "bonjour" (j'ai laissé tomber la correspondance $ pour la variable passée dans, dans la même ligne)
Cliffordlife
1
Fantastique morceau de code! Merci! Cependant, cela ne semble pas fonctionner dans tous les cas. Résultat des tests sur mon ubuntu 18.04 avec php 7.2.19: ne fonctionne pas lorsqu'il est utilisé plusieurs fois sur la même ligne de code, qu'il soit utilisé dans une ou plusieurs expressions distinctes, car il renvoie alors le nom de la dernière variable du ligne. S'il est utilisé dans la même expression mais sur des lignes distinctes, cela fonctionne. Utilisé dans différentes expressions sur différentes lignes, cela fonctionne.
Matty
1
cette fonction doit également être sur une seule ligne sans "var_dump" - avec une print_var_name, echo, var_dumpsortie d'envoi combinée$variable); echo ' '; var_dump($variable
BG Bruno
13

Lucas sur PHP.net a fourni un moyen fiable de vérifier si une variable existe. Dans son exemple, il parcourt une copie du tableau de variables globales (ou un tableau de portée) de variables, modifie la valeur en une valeur générée aléatoirement et vérifie la valeur générée dans le tableau copié.

function variable_name( &$var, $scope=false, $prefix='UNIQUE', $suffix='VARIABLE' ){
    if($scope) {
        $vals = $scope;
    } else {
        $vals = $GLOBALS;
    }
    $old = $var;
    $var = $new = $prefix.rand().$suffix;
    $vname = FALSE;
    foreach($vals as $key => $val) {
        if($val === $new) $vname = $key;
    }
    $var = $old;
    return $vname;
}

Puis essayez:

$a = 'asdf';
$b = 'asdf';
$c = FALSE;
$d = FALSE;

echo variable_name($a); // a
echo variable_name($b); // b
echo variable_name($c); // c
echo variable_name($d); // d

N'oubliez pas de vérifier son message sur PHP.net: http://php.net/manual/en/language.variables.php

Ouvrier
la source
Comment obtenir la portée actuelle sous forme de tableau?
Sebastián Grignoli
Agréable! Pour moi, il ne manque que break;lorsqu'il est trouvé égal dans foreach + J'ai fait une structure de base utilisable pour obtenir automatiquement var_name également si elle est définie dans la fonction. Si vous faites souvent du copier-coller ou avez une meilleure idée pour l'améliorer, utilisezvariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2
C'est probablement le moyen le plus rapide et le plus propre de faire le travail, le débogage inclut probablement des problèmes de performances. La fonction doit retourner directement dans la boucle foreach au lieu de simplement l'affecter sans interruption. Étant donné que les GLOBAUX peuvent être grands, cela peut être une amélioration des performances.
John
13

J'ai fait une fonction d'inspection pour des raisons de débogage. C'est comme print_r () sur les stéroïdes, un peu comme Krumo mais un peu plus efficace sur les objets. Je voulais ajouter la détection du nom var et je suis sorti avec cela, inspiré par le post de Nick Presta sur cette page. Il détecte toute expression passée en argument, pas seulement les noms de variables.

Il s'agit uniquement de la fonction wrapper qui détecte l'expression transmise. Fonctionne sur la plupart des cas. Cela ne fonctionnera pas si vous appelez la fonction plusieurs fois dans la même ligne de code.

Cela fonctionne bien: mourir ( inspecter ($ this-> getUser () -> hasCredential ("supprimer")) );

inspect () est la fonction qui détectera l'expression passée.

Nous obtenons: $ this-> getUser () -> hasCredential ("delete")

function inspect($label, $value = "__undefin_e_d__")
{
    if($value == "__undefin_e_d__") {

        /* The first argument is not the label but the 
           variable to inspect itself, so we need a label.
           Let's try to find out it's name by peeking at 
           the source code. 
        */

        /* The reason for using an exotic string like 
           "__undefin_e_d__" instead of NULL here is that 
           inspected variables can also be NULL and I want 
           to inspect them anyway.
        */

        $value = $label;

        $bt = debug_backtrace();
        $src = file($bt[0]["file"]);
        $line = $src[ $bt[0]['line'] - 1 ];

        // let's match the function call and the last closing bracket
        preg_match( "#inspect\((.+)\)#", $line, $match );

        /* let's count brackets to see how many of them actually belongs 
           to the var name
           Eg:   die(inspect($this->getUser()->hasCredential("delete")));
                  We want:   $this->getUser()->hasCredential("delete")
        */
        $max = strlen($match[1]);
        $varname = "";
        $c = 0;
        for($i = 0; $i < $max; $i++){
            if(     $match[1]{$i} == "(" ) $c++;
            elseif( $match[1]{$i} == ")" ) $c--;
            if($c < 0) break;
            $varname .=  $match[1]{$i};
        }
        $label = $varname;
    }

    // $label now holds the name of the passed variable ($ included)
    // Eg:   inspect($hello) 
    //             => $label = "$hello"
    // or the whole expression evaluated
    // Eg:   inspect($this->getUser()->hasCredential("delete"))
    //             => $label = "$this->getUser()->hasCredential(\"delete\")"

    // now the actual function call to the inspector method, 
    // passing the var name as the label:

      // return dInspect::dump($label, $val);
         // UPDATE: I commented this line because people got confused about 
         // the dInspect class, wich has nothing to do with the issue here.

    echo("The label is: ".$label);
    echo("The value is: ".$value);

}

Voici un exemple de la fonction inspecteur (et de ma classe dInspect) en action:

http://inspect.ip1.cc

Les textes sont en espagnol sur cette page, mais le code est concis et vraiment facile à comprendre.

Sebastián Grignoli
la source
1
errrm, cela ne dépend-il pas de l'installation du débogueur NuSphare?
Mawg dit réintégrer Monica le
J'ai posté une version simplifiée de ce code là-bas. J'ai aussi modifié cette réponse. Il devrait maintenant fonctionner sur chaque implémentation de PHP5.
Sebastián Grignoli
L'ingéniosité comme celle-ci est la raison pour laquelle je souris chaque fois que je vois des gens dire "c'est impossible" ou "pas possible", ce qui inclut même Rasmus lui-même dans ce cas. Félicitations à Sebastián et à toute autre personne qui aurait pu contribuer à cette réponse.
Night Owl
1
Merci Night Owl, mais j'insiste sur le fait que ce n'est pas à l'épreuve des balles (comme l'indique la réponse, il échouera si ma fonction "inspect ()" est appelée plus d'une fois sur une seule ligne!). Je ne l'utiliserais jamais en production. C'est seulement pour une fonction d'inspecteur de débogage qui ne devrait jamais atteindre le serveur de production.
Sebastián Grignoli
7

De php.net

@Alexandre - solution courte

<?php
function vname(&$var, $scope=0)
{
    $old = $var;
    if (($key = array_search($var = 'unique'.rand().'value', !$scope ? $GLOBALS : $scope)) && $var = $old) return $key;  
}
?>

@Lucas - utilisation

<?php
//1.  Use of a variable contained in the global scope (default):
  $my_global_variable = "My global string.";
  echo vname($my_global_variable); // Outputs:  my_global_variable

//2.  Use of a local variable:
  function my_local_func()
  {
    $my_local_variable = "My local string.";
    return vname($my_local_variable, get_defined_vars());
  }
  echo my_local_func(); // Outputs: my_local_variable

//3.  Use of an object property:
  class myclass
  {
    public function __constructor()
    {
      $this->my_object_property = "My object property  string.";
    }
  }
  $obj = new myclass;
  echo vname($obj->my_object_property, $obj); // Outputs: my_object_property
?>

la source
4

De nombreuses réponses s'interrogent sur l'utilité de cela. Cependant, obtenir une référence pour une variable peut être très utile. Surtout dans les cas avec des objets et $ this . Ma solution fonctionne avec des objets, ainsi qu'en tant qu'objets définis par propriété:

function getReference(&$var)
{
    if(is_object($var))
        $var->___uniqid = uniqid();
    else
        $var = serialize($var);
    $name = getReference_traverse($var,$GLOBALS);
    if(is_object($var))
        unset($var->___uniqid);
    else
        $var = unserialize($var);
    return "\${$name}";    
}

function getReference_traverse(&$var,$arr)
{
    if($name = array_search($var,$arr,true))
        return "{$name}";
    foreach($arr as $key=>$value)
        if(is_object($value))
            if($name = getReference_traverse($var,get_object_vars($value)))
                return "{$key}->{$name}";
}

Exemple pour ce qui précède:

class A
{
    public function whatIs()
    {
        echo getReference($this);
    }
}

$B = 12;
$C = 12;
$D = new A;

echo getReference($B)."<br/>"; //$B
echo getReference($C)."<br/>"; //$C
$D->whatIs(); //$D
K. Brunner
la source
2

Adapté des réponses ci-dessus pour de nombreuses variables, avec de bonnes performances, une seule analyse $ GLOBALS pour plusieurs

function compact_assoc(&$v1='__undefined__', &$v2='__undefined__',&$v3='__undefined__',&$v4='__undefined__',&$v5='__undefined__',&$v6='__undefined__',&$v7='__undefined__',&$v8='__undefined__',&$v9='__undefined__',&$v10='__undefined__',&$v11='__undefined__',&$v12='__undefined__',&$v13='__undefined__',&$v14='__undefined__',&$v15='__undefined__',&$v16='__undefined__',&$v17='__undefined__',&$v18='__undefined__',&$v19='__undefined__'
) {
    $defined_vars=get_defined_vars();

    $result=Array();
    $reverse_key=Array();
    $original_value=Array();
    foreach( $defined_vars as $source_key => $source_value){
        if($source_value==='__undefined__') break;
        $original_value[$source_key]=$$source_key;
        $new_test_value="PREFIX".rand()."SUFIX";
        $reverse_key[$new_test_value]=$source_key;
        $$source_key=$new_test_value;

    }
    foreach($GLOBALS as $key => &$value){
        if( is_string($value) && isset($reverse_key[$value])  ) {
            $result[$key]=&$value;
        }
    }
    foreach( $original_value as $source_key => $original_value){
        $$source_key=$original_value;
    }
    return $result;
}


$a = 'A';
$b = 'B';
$c = '999';
$myArray=Array ('id'=>'id123','name'=>'Foo');
print_r(compact_assoc($a,$b,$c,$myArray) );

//print
Array
(
    [a] => A
    [b] => B
    [c] => 999
    [myArray] => Array
        (
            [id] => id123
            [name] => Foo
        )

)
user1933288
la source
1

Si la variable est interchangeable, vous devez avoir une logique quelque part qui détermine quelle variable sera utilisée. Il vous suffit de mettre le nom de la variable dans$variable dans cette logique pendant que vous faites tout le reste.

Je pense que nous avons tous du mal à comprendre pourquoi vous en avez besoin. Un exemple de code ou une explication de ce que vous essayez de faire pourrait aider, mais je pense que vous êtes en train de penser à cela.

ceejayoz
la source
1

J'ai en fait un cas d'utilisation valide pour cela.

J'ai une fonction cacheVariable ($ var) (ok, j'ai un cache de fonction ($ key, $ value), mais j'aimerais avoir une fonction comme mentionné).

Le but est de faire:

$colour = 'blue';
cacheVariable($colour);

...

// another session

...

$myColour = getCachedVariable('colour');

J'ai essayé avec

function cacheVariable($variable) {
   $key = ${$variable}; // This doesn't help! It only gives 'variable'.
   // do some caching using suitable backend such as apc, memcache or ramdisk
}

J'ai aussi essayé avec

function varName(&$var) {
   $definedVariables = get_defined_vars();
   $copyOfDefinedVariables = array();
   foreach ($definedVariables as $variable=>$value) {
      $copyOfDefinedVariables[$variable] = $value;
   }
   $oldVar = $var;
   $var = !$var;
   $difference = array_diff_assoc($definedVariables, $copyOfDefinedVariables);
   $var = $oldVar;
   return key(array_slice($difference, 0, 1, true));
}

Mais cela échoue aussi ... :(

Bien sûr, je pourrais continuer à faire du cache ('color', $ color), mais je suis paresseux, vous savez ...;)

Donc, ce que je veux, c'est une fonction qui obtient le nom ORIGINAL d'une variable, car il a été passé à une fonction. À l'intérieur de la fonction, il n'y a aucun moyen que je puisse savoir cela, comme il semble. Passer get_defined_vars () par référence dans le deuxième exemple ci-dessus m'a un peu aidé (Merci à Jean-Jacques Guegan pour cette idée). Cette dernière fonction a commencé à fonctionner, mais elle n'a continué à renvoyer que la variable locale ('variable', pas 'color').

Je n'ai pas encore essayé d'utiliser get_func_args () et get_func_arg (), $ {} - constructions et key () combinées, mais je suppose que cela échouera également.

Aron Cederholm
la source
1
Le problème très basique est que vous passez des valeurs dans des fonctions, pas des variables . Les variables sont temporaires et particulières à leur portée. Souvent, le nom de la variable peut ne pas être la clé sous laquelle vous souhaitez mettre en cache la valeur, et souvent vous la restaurerez de toute façon dans une variable nommée différemment (comme vous le faites dans votre exemple). Si vous êtes vraiment trop paresseux pour répéter le nom de la clé pour mémoriser la variable, utilisez cacheVariable(compact('color')).
décomposer
1

J'ai ceci:

  debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));

Je préfère ceci:

  debug_echo($query, $nrUsers, $hdr);

La fonction existante affiche une boîte jaune avec un contour rouge et affiche chaque variable par nom et valeur. La solution de tableau fonctionne mais est un peu compliquée à taper lorsqu'elle est nécessaire.

C'est mon cas d'utilisation et oui, cela a à voir avec le débogage. Je suis d'accord avec ceux qui contestent son utilisation autrement.

Will Fastie
la source
1

Voici ma solution basée sur Jeremy Ruten

class DebugHelper {

    function printVarNames($systemDefinedVars, $varNames) {
        foreach ($systemDefinedVars as $var=>$value) {
            if (in_array($var, $varNames )) {
                var_dump($var);
                var_dump($value);
            }
        }
    }
}

En l'utilisant

DebugHelper::printVarNames(
    $systemDefinedVars = get_defined_vars(),
    $varNames=array('yourVar00', 'yourVar01')
);
dakiquang
la source
0

Pourquoi ne construisez-vous pas simplement une fonction simple et DITES-LE?

/**
 * Prints out $obj for debug
 *
 * @param any_type $obj
 * @param (string) $title
 */
function print_all( $obj, $title = false )
{
    print "\n<div style=\"font-family:Arial;\">\n";
    if( $title ) print "<div style=\"background-color:red; color:white; font-size:16px; font-weight:bold; margin:0; padding:10px; text-align:center;\">$title</div>\n";
    print "<pre style=\"background-color:yellow; border:2px solid red; color:black; margin:0; padding:10px;\">\n\n";
    var_export( $obj );
    print "\n\n</pre>\n</div>\n";
}

print_all( $aUser, '$aUser' );
Un vieil homme
la source
0

Je cherchais cela, mais j'ai juste décidé de passer le nom, j'ai généralement le nom dans le presse-papiers de toute façon.

function VarTest($my_var,$my_var_name){
    echo '$'.$my_var_name.': '.$my_var.'<br />';
}

$fruit='apple';
VarTest($fruit,'fruit');
Kieron Axten
la source
0

Vous pouvez utiliser compact () pour y parvenir.

$FooBar = "a string";

$newArray = compact('FooBar');

Cela créerait un tableau associatif avec le nom de variable comme clé. Vous pouvez ensuite parcourir le tableau en utilisant le nom de clé où vous en avez besoin.

foreach($newarray as $key => $value) {
    echo $key;
}
Budove
la source
2
Cool mais il faut connaître le nom de la variable pour l'utiliser. OP cherche à déterminer par programme le nom de la variable.
un codeur
0

Je pense que vous voulez connaître le nom de la variable avec sa valeur. Vous pouvez utiliser un tableau associatif pour y parvenir.

utilisez des noms de variables pour les clés de tableau:

$vars = array('FooBar' => 'a string');

Lorsque vous voulez obtenir des noms de variables, utilisez array_keys($vars), il retournera un tableau de ces noms de variables utilisés dans votre $varstableau comme clés.

Janaka R Rajapaksha
la source
Beaucoup plus lent que les méthodes plus habituelles de déclaration de variables.
David Spector
0

Je sais que c'est vieux et déjà répondu, mais je cherchais réellement cela. Je poste cette réponse pour faire gagner un peu de temps aux gens pour affiner certaines des réponses.

Option 1:

$data = array('$FooBar');  

$vars = [];  
$vars = preg_replace('/^\\$/', '', $data); 

$varname = key(compact($vars));  
echo $varname;

Tirages:

FooBar

Pour une raison quelconque, vous vous retrouveriez dans une situation comme celle-ci, cela fonctionne réellement.

.
Option 2:

$FooBar = "a string";  

$varname = trim(array_search($FooBar, $GLOBALS), " \t.");  
echo $varname;

S'il $FooBarcontient une valeur unique, il affichera 'FooBar'. Si$FooBar est vide ou nul, il affichera le nom de la première chaîne vide ou nulle qu'il trouve.

Il pourrait être utilisé comme tel:

if (isset($FooBar) && !is_null($FooBar) && !empty($FooBar)) {
    $FooBar = "a string";
    $varname = trim(array_search($FooBar, $GLOBALS), " \t.");
}
Stuperfied
la source
0

C'est comme ça que je l'ai fait

function getVar(&$var) {
    $tmp = $var; // store the variable value
    $var = '_$_%&33xc$%^*7_r4'; // give the variable a new unique value
    $name = array_search($var, $GLOBALS); // search $GLOBALS for that unique value and return the key(variable)
    $var = $tmp; // restore the variable old value
    return $name;
}

Usage

$city  = "San Francisco";
echo getVar($city); // city

Remarque: certaines versions de PHP 7 ne fonctionneront pas correctement en raison d'un bogue array_searchavec $GLOBALS, mais toutes les autres versions fonctionneront.

Voir ce https://3v4l.org/UMW7V

Pluie
la source
-1

Utilisez-le pour détacher les variables utilisateur du global pour vérifier la variable pour le moment.

function get_user_var_defined () 
{
    return array_slice($GLOBALS,8,count($GLOBALS)-8);     
}

function get_var_name ($var) 
{
    $vuser = get_user_var_defined(); 
    foreach($vuser as $key=>$value) 
    {
        if($var===$value) return $key ; 
    }
}
user1446000
la source
@IMSoP A en juger par sa sortie, print implode( ' ', array_keys( $GLOBALS ));cela ressemble à une hypothèse erronée sur le nombre de globaux "par défaut". Sur mon système, il y a sept superglobales: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Et il y a aussi argv et argc. Le décalage devrait donc être de 9. Et il est inutile de spécifier le troisième paramètre (longueur), car la valeur par défaut est juste de courir de toute façon jusqu'à la fin du tableau.
Jeff
-2

Cela peut être considéré comme rapide et sale, mais ma préférence personnelle est d'utiliser une fonction / méthode comme celle-ci:

public function getVarName($var) {      
  $tmp = array($var => '');
  $keys = array_keys($tmp);
  return trim($keys[0]);
}

Fondamentalement, il crée simplement un tableau associatif contenant un élément nul / vide, en utilisant comme clé la variable dont vous voulez le nom.

nous obtenons ensuite la valeur de cette clé en utilisant array_keys et la retournons.

de toute évidence, cela devient rapidement désordonné et ne serait pas souhaitable dans un environnement de production, mais cela fonctionne pour le problème présenté.

user3344253
la source
1
C'est la valeur de la variable, pas le nom de la variable. Comme indiqué ailleurs, le nom n'est pas portable au-delà des limites des fonctions.
Owen Beresford
3
moins un car cette fonction est littéralement ne fait que renvoyer le trim ($ var);
Alexar
-3

pourquoi nous devons utiliser des globaux pour obtenir le nom de variable ... nous pouvons utiliser simplement comme ci-dessous.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }
Ajaxmint
la source
6
Parce que l'OP ne connaît pas le nom de la variable. S'il le faisait, il n'aurait pas besoin d'une getVarName()fonction. ;-)
FtDRbwLXw6
1
Cela ne renvoie pas le nom d'une variable sous forme de chaîne, car il '$variableName's'agit déjà d'une chaîne, pas d'une variable. Si vous pouvez faire ce tour avec getVarName($variableName);, vous obtenez un vote positif :)
Daniel W.
-4

Je ne vois vraiment pas le cas d'utilisation ... Si vous tapez print_var_name ($ foobar), qu'est-ce qui est si difficile (et différent) à la place de print ("foobar")?

Parce que même si vous deviez utiliser ceci dans une fonction, vous obtiendriez le nom local de la variable ...

Dans tous les cas, voici le manuel de réflexion au cas où vous auriez besoin de quelque chose.

Vinko Vrsalovic
la source
L'impression ("foobar") ne gérera pas les autres variables.
Gary Willoughby
7
Cas d'utilisation: vous avez peu de points de débogage dans le code renvoyant le vidage de la même valeur. Comment savez-vous lequel a été exécuté en premier? L'impression d'une étiquette est alors très utile.
takehin
Ensuite, vous n'avez pas fait assez de programmation. La plupart des langues que j'ai rencontrées ont un moyen de le faire, généralement simple.
b01
@ b01 J'en ai fait beaucoup. Je suis parfaitement conscient qu'il existe de nombreuses langues qui permettent cela, mais cela en soi ne signifie pas grand-chose. De nombreuses langues offrent un moyen de le faire facilement et cela ne signifie pas que vous devez l'utiliser pour éviter d'écrire un contrôle de flux approprié. C'est un cas similaire à mon avis. Je ne doute pas qu'il existe des cas justifiables, et c'est pourquoi je me demandais quels étaient les cas d'utilisation appropriés.
Vinko Vrsalovic