Wie bekomme ich einen Variablennamen als String in PHP?

Lesezeit: 13 Minuten

Angenommen, ich habe diesen PHP-Code:

$FooBar = "a string";

Ich brauche dann eine Funktion wie diese:

print_var_name($FooBar);

was druckt:

FooBar

Irgendwelche Ideen, wie man dies erreichen kann? Ist das in PHP überhaupt möglich?

  • Wenn Sie dies für etwas anderes als zum Debuggen benötigen, machen Sie etwas ernsthaft falsch. Was ist Ihr Anwendungsfall?

    – troelskn

    1. November 2008 um 17:26 Uhr

  • Gute Frage. Ich brauchte das gleiche für das Debuggen.

    – nimmthin

    19. März 2011 um 16:00 Uhr

  • +1 – Ich brauchte dies zum automatischen Generieren von XML- oder JSON-Antworten aus einem Modell-PHP-Objekt. Das Objekt muss in ein anderes Named eingeschlossen werden rootName => modelObject array fügt der Antwort nur unnötige Tiefe hinzu. Wünschte, dies wäre in die Laufzeitreflexionsfähigkeiten der Sprache eingebrannt.

    – Anurag

    16. Mai 2011 um 20:18 Uhr


  • Ich hatte auch einen Bedarf dafür in einer Protokollierungsfunktion. Ich wollte Folgendes tun können: log($didTheSystemBlowUp); Um in der Protokolldatei zu erscheinen: $didTheSystemBlowUp = ‘noch nicht, aber sehr bald’;

    – SeanDowney

    23. Mai 2012 um 17:36 Uhr


  • Dies kann auch beim Aufrufen von var_dump() nützlich sein, wenn Sie also mehrere Variablen gleichzeitig aufrufen, müssen Sie den var-Namen nicht manuell ausgeben, um zwischen den Ausgaben von vardumps zu unterscheiden.

    – Hübscher Nerd

    3. Dezember 2012 um 5:50 Uhr


Ich konnte mir auch keinen Weg vorstellen, dies effizient zu tun, aber ich habe mir das ausgedacht. Es funktioniert für die folgenden begrenzten Verwendungszwecke.

zucken

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

Es funktioniert basierend auf der Zeile, die die Funktion aufgerufen hat, wo es das Argument findet, das Sie übergeben haben. Ich nehme an, es könnte erweitert werden, um mit mehreren Argumenten zu arbeiten, aber, wie andere gesagt haben, wenn Sie die Situation besser erklären könnten, wäre es wahrscheinlich eine andere Lösung arbeite besser.

  • Das funktioniert, aber nur, wenn die Funktion varName in derselben Datei wie die zu findende Variable definiert ist.

    – rubo77

    5. November 2013 um 11:56 Uhr

  • Hier finden Sie eine bessere Implementierung, die über mehrere Includes funktioniert: stackoverflow.com/a/19788805/1069083

    – rubo77

    5. November 2013 um 12:35 Uhr

Wie bekomme ich einen Variablennamen als String in PHP
Paige Rüten

Du könntest benutzen get_defined_vars() um den Namen einer Variablen zu finden, die denselben Wert hat wie diejenige, deren Namen Sie zu finden versuchen. Natürlich wird das nicht immer funktionieren, da verschiedene Variablen oft die gleichen Werte haben, aber es ist die einzige Möglichkeit, die ich mir vorstellen kann, dies zu tun.

Bearbeiten: get_defined_vars() scheint nicht richtig zu funktionieren, es gibt ‘var’ zurück, weil $var in der Funktion selbst verwendet wird. $GLOBALS scheint zu funktionieren, also habe ich es dahingehend geändert.

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

    return false;
}

Bearbeiten: Um es klar zu sagen, es gibt keine gute Möglichkeit, dies in PHP zu tun, was wahrscheinlich daran liegt, dass Sie es nicht tun sollten. Es gibt wahrscheinlich bessere Möglichkeiten, das zu tun, was Sie zu tun versuchen.

  • Ahh. War zu langsam 😉 Das gleiche gedacht, aber stattdessen $GLOBALS verwendet. Der Identitätsvergleich ergibt also true für gleiche skalare Werte ($a = ‘foo’; $b = ‘foo’; assert($a === $b);)?

    – Argelbargel

    1. November 2008 um 0:46 Uhr

  • Jetzt, wo ich meinen Code getestet habe, hat mein Code immer ‘var’ zurückgegeben, weil es in der Funktion verwendet wird. Wenn ich stattdessen $GLOBALS verwende, gibt es aus irgendeinem Grund den richtigen Variablennamen zurück. Also werde ich den obigen Code ändern, um $GLOBALS zu verwenden.

    – Paige Ruten

    1. November 2008 um 1:11 Uhr

  • Es gibt viele Fälle, in denen sich dieser Code nicht wie erwartet verhält.

    – troelskn

    1. November 2008 um 17:25 Uhr

  • Dieser Code ist SCHRECKLICH falsch. Zu überprüfen, ob die Variable dieselbe ist wie die, die von VALUE gesendet wird, ist eine sehr dumme Idee. Myriaden von Variablen sind an jedem beliebigen Punkt NULL. Myriads sind auf 1 gesetzt. Das ist einfach verrückt.

    – Alex Weinstein

    10. März 2010 um 5:44 Uhr

  • Versuchen Sie Ihren Code mit $a = 10; $ b = 10; print_r(print_var_name($b));

    – Ashish Rana

    26. August 2017 um 7:12 Uhr

Sie könnten erwägen, Ihren Ansatz zu ändern und einen variablen Variablennamen zu verwenden?

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

dann könntest du eben

print($var_name);

bekommen

FooBar

Hier ist der Link zum PHP-Handbuch zu Variablen-Variablen

  • Ich habe mit einem System gearbeitet, das ausgiebig Variablen verwendet hat. Lassen Sie mich Sie warnen, es wird wirklich sehr schnell stinken!

    – Icode4food

    14. Oktober 2010 um 13:47 Uhr

  • In den meisten Fällen möchte der Benutzer den Namen und Wert einer Variablen erhalten. Denken Sie “Funktion debugvar($varname)” und er beabsichtigt, es “debugvar(‘foo’)” zu nennen, damit der Debug “foo = 123” anzeigt. mit variabler Variable erhalten sie ‘foo’ ist undefiniert.

    – gcb

    14. April 2011 um 8:01 Uhr

  • Schau dir einfach an, was du wirklich tust. Genau dort in Ihrem Beispiel erstellen Sie tatsächlich eine Variable $FooBar mit dem Wert a string lies einfach mal dein handbuch. Das ist imho schrecklich. Sie weisen die Variable niemals zu $FooBar ein Wert, aber es ist da. AUTSCH

    – Toskanisch

    17. Juni 2014 um 7:47 Uhr

Niemand scheint die grundlegenden Gründe genannt zu haben warum das ist a) hart und b) unklug:

  • Eine “Variable” ist nur ein Symbol, das auf etwas anderes zeigt. In PHP zeigt es intern auf etwas namens “zval”, das tatsächlich für mehrere Variablen gleichzeitig verwendet werden kann, entweder weil sie denselben Wert haben (PHP implementiert etwas namens “copy-on-write”, so dass $foo = $bar muss nicht sofort zusätzlichen Speicher zuweisen) oder weil sie per Referenz zugewiesen (oder an eine Funktion übergeben) wurden (z $foo =& $bar). Ein zval hat also keinen Namen.
  • Wenn Sie einen Parameter an eine Funktion übergeben, erstellen Sie eine Neu Variable (auch wenn es sich um eine Referenz handelt). Sie könnten etwas Anonymes weitergeben, wie z "hello", aber sobald Sie sich in Ihrer Funktion befinden, ist es die Variable, als die Sie sie benennen. Dies ist ziemlich grundlegend für die Codetrennung: Wenn sich eine Funktion auf was für eine Variable stützt benutzt angerufen werden, es wäre eher wie a goto als eine richtig getrennte Funktion.
  • Globale Variablen werden im Allgemeinen als schlechte Idee angesehen. Viele der Beispiele hier gehen davon aus, dass die Variable, die Sie “reflektieren” möchten, in gefunden werden kann $GLOBALSaber das trifft nur zu, wenn Sie Ihren Code schlecht strukturiert haben und Variablen nicht auf eine Funktion oder ein Objekt beschränkt sind.
  • Variablennamen sollen Programmierern helfen, ihren Code zu lesen. Das Umbenennen von Variablen, damit sie ihrem Zweck besser entsprechen, ist eine sehr verbreitete Refactoring-Praxis, und der springende Punkt ist, dass es keinen Unterschied macht.

Nun, ich verstehe den Wunsch danach zum Debuggen (obwohl einige der vorgeschlagenen Verwendungen weit darüber hinausgehen), aber als verallgemeinerte Lösung ist es nicht so hilfreich, wie Sie vielleicht denken: Wenn Ihre Debug-Funktion sagt, dass Ihre Variable “$file “, das könnte immer noch eine von Dutzenden von „$file“-Variablen in Ihrem Code sein, oder eine Variable, die Sie „$filename“ genannt haben, aber an eine Funktion übergeben, deren Parameter „$file“ heißt.

Eine weitaus nützlichere Information ist, wo in Ihrem Code die Debug-Funktion aufgerufen wurde. Da Sie dies schnell in Ihrem Editor finden, können Sie sehen, welche Variable Sie für sich selbst ausgegeben haben, und können sogar ganze Ausdrücke auf einmal übergeben (z debug('$foo + $bar=" . ($foo + $bar))).

Dazu können Sie dieses Snippet oben in Ihrer Debug-Funktion verwenden:

$backtrace = debug_backtrace();
echo "# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];

1646976854 451 Wie bekomme ich einen Variablennamen als String in PHP
Adilbo

Das ist genau das, was Sie wollen – es ist eine gebrauchsfertige “Kopieren und Einfügen”-Funktion, die den Namen einer bestimmten Variable widerspiegelt:

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 '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>';
}

VERWENDUNG: print_var_name($FooBar)

DRUCKEN: FooBar

HINWEIS

Jetzt können Sie die Funktion umbenennen und es wird trotzdem funktionieren und die Funktion auch mehrmals in einer Zeile verwenden! Danke an @Cliffordlife
Und ich füge eine schönere Ausgabe hinzu! Danke an @Blue-Water

  • Klasse, danke dafür. Ich habe die $pat-Zeile leicht in geändert $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i'; Auf diese Weise ist es mir egal, wie diese Debug-Funktion heißt, und ich bekomme genau das, was an die Funktion übergeben wird, dh $hello oder “hello” (ich habe das $-Match für die übergebene Variable in derselben Zeile gelöscht).

    – Cliffordlife

    16. Juni 2016 um 9:21 Uhr


  • Fantastisches Stück Code! Danke! Allerdings scheint es nicht in allen Fällen zu funktionieren. Ergebnis des Tests auf meinem Ubuntu 18.04 mit PHP 7.2.19: Funktioniert nicht, wenn es mehrmals in derselben Codezeile verwendet wird, unabhängig davon, ob es in einem oder in separaten Ausdrücken verwendet wird, da es dann den Namen der letzten Variablen der zurückgibt Linie. Wenn es im selben Ausdruck, aber in separaten Zeilen verwendet wird, funktioniert es. In verschiedenen Ausdrücken auf verschiedenen Zeilen verwendet, funktioniert es.

    – Matti

    12. Juni 2019 um 7:30 Uhr


  • auch diese Funktion sollte in einer Zeile ohne “var_dump” stehen – mit Kombination print_var_name, echo, var_dump Ausgabe senden $variable); echo ' '; var_dump($variable

    – BGBRUNO

    4. Februar 2020 um 13:50 Uhr


  • Funktioniert hervorragend zum Debuggen.

    – JayJay123

    2. Mai 2021 um 6:40 Uhr

  • Dies ist eine unglaublich kreative Lösung. Hervorragende Funktion! Darüber hinaus hat OP nicht speziell gefragt, weil ich nehme an, dass er sein Problem für die Frage isolierte, aber ich nehme an, OP will auch die Wertausgabe. Um das Schreiben von clientseitigem Code zu vermeiden, kann man die letzte Zeile der Funktion ersetzen durch: echo '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>'; die FooBar = eine Zeichenfolge ausgibt und auch Arrays berücksichtigt.

    Benutzer2607743

    14. Mai 2021 um 21:12 Uhr

Ich habe aus Debugging-Gründen eine Inspektionsfunktion erstellt. Es ist wie print_r() bei Steroiden, ähnlich wie Krumo, aber etwas effektiver bei Objekten. Ich wollte die var-Namenserkennung hinzufügen und bin dabei herausgekommen, inspiriert von Nick Prestas Beitrag auf dieser Seite. Es erkennt jeden als Argument übergebenen Ausdruck, nicht nur Variablennamen.

Dies ist nur die Wrapper-Funktion, die den übergebenen Ausdruck erkennt. Funktioniert in den meisten Fällen. Es funktioniert nicht, wenn Sie die Funktion mehr als einmal in derselben Codezeile aufrufen.

Das funktioniert gut: die(prüfen($this->getUser()->hasCredential(“delete”)));

inspect() ist die Funktion, die den übergebenen Ausdruck erkennt.

Wir bekommen: $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);

}

Hier ist ein Beispiel für die Inspector-Funktion (und meine dInspect-Klasse) in Aktion:

http://inspect.ip1.cc

Die Texte auf dieser Seite sind auf Spanisch, aber der Code ist kurz und wirklich einfach zu verstehen.

  • Klasse, danke dafür. Ich habe die $pat-Zeile leicht in geändert $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i'; Auf diese Weise ist es mir egal, wie diese Debug-Funktion heißt, und ich bekomme genau das, was an die Funktion übergeben wird, dh $hello oder “hello” (ich habe das $-Match für die übergebene Variable in derselben Zeile gelöscht).

    – Cliffordlife

    16. Juni 2016 um 9:21 Uhr


  • Fantastisches Stück Code! Danke! Allerdings scheint es nicht in allen Fällen zu funktionieren. Ergebnis des Tests auf meinem Ubuntu 18.04 mit PHP 7.2.19: Funktioniert nicht, wenn es mehrmals in derselben Codezeile verwendet wird, unabhängig davon, ob es in einem oder in separaten Ausdrücken verwendet wird, da es dann den Namen der letzten Variablen der zurückgibt Linie. Wenn es im selben Ausdruck, aber in separaten Zeilen verwendet wird, funktioniert es. In verschiedenen Ausdrücken auf verschiedenen Zeilen verwendet, funktioniert es.

    – Matti

    12. Juni 2019 um 7:30 Uhr


  • auch diese Funktion sollte in einer Zeile ohne “var_dump” stehen – mit Kombination print_var_name, echo, var_dump Ausgabe senden $variable); echo ' '; var_dump($variable

    – BGBRUNO

    4. Februar 2020 um 13:50 Uhr


  • Funktioniert hervorragend zum Debuggen.

    – JayJay123

    2. Mai 2021 um 6:40 Uhr

  • Dies ist eine unglaublich kreative Lösung. Hervorragende Funktion! Darüber hinaus hat OP nicht speziell gefragt, weil ich nehme an, dass er sein Problem für die Frage isolierte, aber ich nehme an, OP will auch die Wertausgabe. Um das Schreiben von clientseitigem Code zu vermeiden, kann man die letzte Zeile der Funktion ersetzen durch: echo '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>'; die FooBar = eine Zeichenfolge ausgibt und auch Arrays berücksichtigt.

    Benutzer2607743

    14. Mai 2021 um 21:12 Uhr

Wie bekomme ich einen Variablennamen als String in PHP
Arbeiter

Lucas auf PHP.net bot eine zuverlässige Methode, um zu prüfen, ob eine Variable existiert. In seinem Beispiel durchläuft er eine Kopie des globalen Variablen-Arrays (oder eines Bereichs-Arrays) von Variablen, ändert den Wert in einen zufällig generierten Wert und sucht nach dem generierten Wert im kopierten Array.

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;
}

Dann versuche es:

$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

Achten Sie darauf, seinen Beitrag auf PHP.net zu überprüfen: http://php.net/manual/en/language.variables.php

  • Wie erhalten Sie den aktuellen Bereich in Array-Form?

    – Sebastián Grignoli

    27. Oktober 2010 um 15:18 Uhr

  • Hübsch! Für mich fehlt nur noch break; wenn in foreach + gleich gefunden, habe ich eine brauchbare Grundstruktur erstellt, um var_name automatisch zu erhalten, auch wenn es innerhalb der Funktion definiert ist. Wenn Sie häufig Copy&Paste verwenden oder eine bessere Idee haben, es zu verbessern, verwenden Sie es variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );

    – odie2

    5. Juni 2015 um 21:12 Uhr

  • Dies ist wahrscheinlich der schnellste und sauberste Weg, um die Arbeit zu erledigen, das Debuggen beinhaltet wahrscheinlich Leistungsprobleme. Die Funktion sollte direkt in der foreach-Schleife zurückgegeben werden, anstatt nur ohne Unterbrechung zuzuweisen. Angesichts der Tatsache, dass die GLOBALS groß sein können, kann dies eine ziemliche Leistungsverbesserung sein.

    – John

    25. Oktober 2019 um 16:27 Uhr

989990cookie-checkWie bekomme ich einen Variablennamen als String in PHP?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy