Come ottenere un nome di variabile come stringa in PHP?


201

Di 'che ho questo codice PHP:

$FooBar = "a string";

ho quindi bisogno di una funzione come questa:

print_var_name($FooBar);

che stampa:

FooBar

Qualche idea su come raggiungere questo obiettivo? È possibile anche in PHP?


9
Se hai bisogno di questo per tutto tranne che per il debug, stai facendo qualcosa di gravemente sbagliato. Qual è il tuo caso d'uso?
troelskn,

10
Buona domanda. Avevo bisogno dello stesso per il debug.
data

17
+1 - Ne avevo bisogno per generare automaticamente una risposta XML o JSON da un oggetto modello PHP. Dover avvolgere l'oggetto all'interno di un altro rootName => modelObjectarray denominato aggiunge semplicemente una profondità non necessaria alla risposta. Vorrei che questo fosse integrato nelle capacità di riflessione del runtime del linguaggio.
Anurag

4
Ne avevo anche bisogno in una funzione di registrazione. Volevo essere in grado di fare quanto segue: log ($ didTheSystemBlowUp); Per apparire nel file di registro come: $ didTheSystemBlowUp = 'non ancora, ma molto presto';
SeanDowney,

4
Inoltre, questo può essere utile quando si chiama var_dump (), quindi quando si chiama contemporaneamente su più variabili non è stato emesso manualmente il nome var per distinguere tra output di vardupms.
PHPst

Risposte:


37

È possibile utilizzare get_defined_vars () per trovare il nome di una variabile che ha lo stesso valore di quella di cui si sta tentando di trovare il nome. Ovviamente questo non funzionerà sempre, poiché variabili diverse spesso hanno gli stessi valori, ma è l'unico modo in cui riesco a pensare di farlo.

Modifica: get_defined_vars () non sembra funzionare correttamente, restituisce 'var' perché $ var viene usato nella funzione stessa. $ GLOBALS sembra funzionare, quindi l'ho cambiato in questo.

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

    return false;
}

Modifica: per essere chiari, non esiste un buon modo per farlo in PHP, probabilmente perché non dovresti farlo. Probabilmente ci sono modi migliori per fare ciò che stai cercando di fare.


2
Ahh. State rallentando ;-) Pensato lo stesso, ma usando invece $ GLOBALS. Quindi il confronto delle identità ha valore vero per valori scalari uguali ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel,

In realtà ora che ho testato il mio codice, il mio codice ha sempre restituito 'var' perché viene utilizzato nella funzione. Quando uso invece $ GLOBALS, per qualche motivo restituisce il nome della variabile corretta. Quindi cambierò il codice sopra per usare $ GLOBALS.
Jeremy Ruten,

Sì, ho capito ma get_defined_vars () era abbastanza ta.
Gary Willoughby,

2
Ci sono molti casi in cui questo codice non si comporterà come previsto.
troelskn,

122
Questo codice è orribilmente errato. Controllare se la variabile è la stessa di quella inviata da VALUE è un'idea molto stupida. Miriadi di variabili sono NULL in un dato punto. Le miriadi sono impostate su 1. Questo è semplicemente pazzo.
Alex Weinstein,

49

Non riuscivo nemmeno a pensare a un modo per farlo in modo efficiente, ma mi sono inventato questo. Funziona, per gli usi limitati di seguito.

alzata di spalle

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

Funziona in base alla linea che ha chiamato la funzione, dove trova l'argomento che hai passato. Suppongo che potrebbe essere espanso per funzionare con più argomenti ma, come altri hanno già detto, se tu potessi spiegare meglio la situazione, probabilmente un'altra soluzione lavorare meglio.


2
Funziona, ma solo se la funzione varName è definita nello stesso file della variabile da trovare.
rubo77,

1
Qui trovate una migliore attuazione che le opere su più include: stackoverflow.com/a/19788805/1069083
rubo77

31

Potresti considerare di cambiare il tuo approccio e usare un nome variabile variabile?

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

allora potresti solo

print($var_name);

ottenere

FooBar

Ecco il link al manuale di PHP sulle variabili delle variabili


42
Ho lavorato con un sistema che utilizzava ampiamente variabili variabili. Lascia che ti avverta, diventa davvero maleodorante molto velocemente!
Icode4food,

3
la maggior parte dei casi l'utente desidera ottenere il nome e il valore di una var. pensa "funzione debugvar ($ varname)" e intende chiamarlo "debugvar ('pippo')", quindi il debug mostrerà "pippo = 123". con variabile variabile otterranno 'pippo' non è definito.
gcb,

guarda cosa stai effettivamente facendo. Proprio lì nel tuo esempio in realtà CREI una variabile $FooBarcon il valore a stringappena letto il tuo manuale. Questo è un orribile imho. non si assegna mai $FooBarun valore alla variabile , ma è lì. OUCH
Toskan,

20

Nessuno sembra aver menzionato i motivi fondamentali per cui questo è a) difficile eb) poco saggio:

  • Una "variabile" è solo un simbolo che punta a qualcos'altro. In PHP, punta internamente a qualcosa chiamato "zval", che può effettivamente essere utilizzato per più variabili contemporaneamente, sia perché hanno lo stesso valore (PHP implementa qualcosa chiamato "copia su scrittura" in modo che $foo = $barnon sia necessario allocare memoria aggiuntiva immediatamente) o perché sono stati assegnati (o passati a una funzione) per riferimento (ad es $foo =& $bar.). Quindi uno zval non ha nome.
  • Quando si passa un parametro a una funzione, si crea una nuova variabile (anche se è un riferimento). Potresti passare qualcosa di anonimo, come "hello", ma una volta dentro la tua funzione, è qualunque variabile la chiami come. Questo è abbastanza fondamentale per la separazione del codice: se una funzione si basava su ciò che una variabile veniva chiamata, sarebbe più simile gotoa una funzione propriamente separata.
  • Le variabili globali sono generalmente considerate una cattiva idea. Molti degli esempi qui presuppongono che la variabile che si desidera "riflettere" possa essere trovata $GLOBALS, ma ciò sarà vero solo se il codice è stato strutturato in modo errato e le variabili non sono comprese in alcuna funzione o oggetto.
  • I nomi delle variabili sono lì per aiutare i programmatori a leggere il loro codice. Rinominare le variabili per adattarle meglio al loro scopo è una pratica di refactoring molto comune e il punto è che non fa alcuna differenza.

Ora capisco il desiderio di questo per il debug (anche se alcuni degli usi proposti vanno ben oltre), ma come soluzione generalizzata non è effettivamente così utile come potresti pensare: se la tua funzione di debug dice che la tua variabile si chiama "$ file ", potrebbe trattarsi di una qualsiasi delle dozzine di variabili" $ file "nel codice o di una variabile che hai chiamato" $ nomefile "ma che passa a una funzione il cui parametro è chiamato" $ file ".

Un'informazione molto più utile è da dove nel tuo codice è stata chiamata la funzione di debug. Dal momento che puoi trovarlo rapidamente nel tuo editor, puoi vedere quale variabile stavi producendo per te stesso e puoi persino passare intere espressioni in esso in una sola volta (ad esempio debug('$foo + $bar = ' . ($foo + $bar))).

Per questo, è possibile utilizzare questo frammento nella parte superiore della funzione di debug:

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

Ci sono già alcune buone risposte. Quindi questo è solo essere pessimista anche di fronte alla realtà.
a20

@ a20 Tutte le risposte hanno pesanti avvertenze su quando possono essere usate e quando si romperanno; none è una semplice ricerca da qualsiasi variabile al suo nome, perché in realtà è impossibile. Alcuni fanno molta riflessione funky per scopi di debug, il che va bene; tuttavia, la mia opinione è che stai meglio semplicemente emettendo il numero di riga e cercando tu stesso la linea di origine - o usando un debugger interattivo come XDebug.
IMSoP

14

Questo è esattamente quello che vuoi - è una funzione "copia e rilascia" pronta per l'uso che fa eco al nome di una data var:

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

USO: print_var_name ($ FooBar)

STAMPA: FooBar

SUGGERIMENTO Ora è possibile rinominare la funzione che funzionerà ancora e che la utilizzerà anche più volte in una riga! Grazie a @Cliffordlife


3
Bene, grazie per questo. Ho modificato leggermente la linea $ pat in $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';questo modo non mi interessa come si chiama questa funzione di debug e ottengo esattamente ciò che viene passato nella funzione, ad esempio $ hello o "hello" (ho lasciato cadere la corrispondenza $ per la variabile passata in, nella stessa linea)
Cliffordlife il

1
Fantastico pezzo di codice! Grazie! Tuttavia, non sembra funzionare in tutti i casi. Risultato del test sul mio ubuntu 18.04 con php 7.2.19: non funziona se usato più volte sulla stessa riga di codice, indipendentemente dal fatto che venga utilizzato in una o espressioni separate, perché restituisce quindi il nome dell'ultima variabile del linea. Se viene utilizzato nella stessa espressione ma su righe separate funziona. Utilizzato in diverse espressioni su diverse linee funziona.
Matty,

1
anche quella funzione dovrebbe essere su una riga senza "var_dump" - con combinazione print_var_name, echo, var_dumpsend output$variable); echo ' '; var_dump($variable
BG Bruno

13

Lucas su PHP.net ha fornito un modo affidabile per verificare l'esistenza di una variabile. Nel suo esempio, scorre una copia dell'array di variabili globale (o un array con ambito) di variabili, cambia il valore in un valore generato casualmente e verifica il valore generato nell'array copiato.

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

Quindi prova:

$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

Assicurati di controllare il suo post su PHP.net: http://php.net/manual/en/language.variables.php


Come si ottiene l'ambito corrente in forma di matrice?
Sebastián Grignoli,

Bello! Per me manca solo break;quando viene trovato uguale in foreach + Ho usato la struttura di base utilizzabile per ottenere automaticamente var_name anche se definito all'interno della funzione. Se sei spesso Copia e incolla o hai un'idea migliore per migliorarlo, usavariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2

Questo è probabilmente il modo più veloce e pulito per fare il lavoro, il debug probabilmente include problemi di prestazioni. La funzione dovrebbe tornare direttamente nel ciclo foreach anziché semplicemente assegnare senza interruzione. Dato che i GLOBALS possono essere grandi, può essere un bel miglioramento delle prestazioni.
Giovanni,

13

Ho effettuato una funzione di ispezione per motivi di debug. È come print_r () sugli steroidi, molto simile a Krumo ma un po 'più efficace sugli oggetti. Volevo aggiungere il rilevamento del nome var e ne sono uscito, ispirato al post di Nick Presta su questa pagina. Rileva qualsiasi espressione passata come argomento, non solo nomi di variabili.

Questa è solo la funzione wrapper che rileva l'espressione passata. Funziona sulla maggior parte dei casi. Non funzionerà se si chiama la funzione più di una volta nella stessa riga di codice.

Funziona bene: die ( inspect ($ This-> getUser () -> hasCredential ( "Elimina")) );

inspect () è la funzione che rileverà l'espressione passata.

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

}

Ecco un esempio della funzione inspector (e della mia classe dInspect) in azione:

http://inspect.ip1.cc

I testi sono in spagnolo in quella pagina, ma il codice è conciso e davvero facile da capire.


1
errrm, non dipende da te se hai installato il debugger NuSphare?
Mawg dice di ripristinare Monica il

Ho pubblicato una versione semplificata di questo codice lì. Anche io ho modificato questa risposta. Ora dovrebbe funzionare su ogni implementazione di PHP5.
Sebastián Grignoli,

Ingenuità come questa è il motivo per cui sorrido ogni volta che vedo la gente dire "impossibile" o "impossibile", che comprende anche lo stesso Rasmus in questo caso. Complimenti a Sebastián e chiunque altro possa aver contribuito a questa risposta.
Gufo notturno

1
Grazie Night Owl, ma insisto sul fatto che questo non è a prova di proiettile (come afferma la risposta, fallirà se la mia funzione "inspect ()" viene chiamata più di una volta in una sola riga!). Non lo userei mai in produzione. È solo per una funzione ispettore di debug che non dovrebbe mai raggiungere il server di produzione.
Sebastián Grignoli

7

Da php.net

@Alexandre - soluzione breve

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

@Lucas - utilizzo

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

4

Molte risposte mettono in dubbio l'utilità di questo. Tuttavia, ottenere un riferimento per una variabile può essere molto utile. Soprattutto nei casi con oggetti e $ questo . La mia soluzione funziona con oggetti e anche come oggetti definiti dalla proprietà:

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

Esempio per quanto sopra:

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

2

Adattato dalle risposte sopra per molte variabili, con buone prestazioni, solo una scansione $ GLOBALS per molte

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
        )

)

1

Se la variabile è intercambiabile, è necessario disporre di una logica da qualche parte che determini quale variabile viene utilizzata. Tutto quello che devi fare è inserire il nome della variabile $variableall'interno di quella logica mentre stai facendo tutto il resto.

Penso che stiamo tutti facendo fatica a capire di cosa hai bisogno. Codice di esempio o una spiegazione di ciò che si sta effettivamente cercando di fare potrebbe aiutare, ma ho il sospetto Non Sei modo, modo overthinking questo.


1

In realtà ho un caso d'uso valido per questo.

Ho una funzione cacheVariable ($ var) (ok, ho una cache di funzione ($ chiave, $ valore), ma vorrei avere una funzione come menzionato).

Lo scopo è di fare:

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

...

// another session

...

$myColour = getCachedVariable('colour');

Ci ho provato

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
}

Ho anche provato con

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

Ma anche questo fallisce ... :(

Certo, potrei continuare a fare cache ('color', $ color), ma sono pigro, sai ...;)

Quindi, quello che voglio è una funzione che ottiene il nome ORIGINALE di una variabile, poiché è stata passata a una funzione. All'interno della funzione non c'è modo di saperlo, come sembra. Passare get_defined_vars () come riferimento nel secondo esempio sopra mi ha aiutato (grazie a Jean-Jacques Guegan per quell'idea) in qualche modo. Quest'ultima funzione ha iniziato a funzionare, ma ha continuato a restituire solo la variabile locale ('variabile', non 'colore').

Non ho ancora provato a usare get_func_args () e get_func_arg (), $ {} - costrutti e key () combinati, ma presumo che fallirà anche.


1
Il problema fondamentale è che stai passando valori in funzioni, non in variabili . Le variabili sono temporanee e particolari per il loro scopo. Spesso il nome della variabile potrebbe non essere la chiave in cui vuoi memorizzare il valore nella cache, e spesso lo ripristinerai comunque in una variabile con un nome diverso (come fai nel tuo esempio). Se sei davvero troppo pigro per ripetere il nome della chiave per ricordare la variabile, usa cacheVariable(compact('color')).
Inganno

1

Ho questo:

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

Preferirei questo:

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

La funzione esistente visualizza una casella gialla con un contorno rosso e mostra ogni variabile per nome e valore. La soluzione array funziona ma è un po 'contorta da digitare quando è necessario.

Questo è il mio caso d'uso e sì, ha a che fare con il debug. Sono d'accordo con coloro che mettono in dubbio il suo utilizzo altrimenti.


1

Ecco la mia soluzione basata su Jeremy Ruten

class DebugHelper {

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

usandolo

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

0

Perché non costruisci semplicemente una funzione e la dici?

/**
 * 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' );

0

Stavo cercando questo, ma ho appena deciso di passare il nome, di solito ho comunque il nome negli Appunti.

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

$fruit='apple';
VarTest($fruit,'fruit');

0

È possibile utilizzare compact () per raggiungere questo obiettivo.

$FooBar = "a string";

$newArray = compact('FooBar');

Ciò creerebbe un array associativo con il nome della variabile come chiave. È quindi possibile eseguire il ciclo attraverso l'array utilizzando il nome della chiave in cui era necessario.

foreach($newarray as $key => $value) {
    echo $key;
}

2
Fantastico ma devi conoscere il nome della variabile per usarlo. OP sta cercando di determinare a livello di codice il nome della variabile.
un programmatore il

0

Penso che tu voglia conoscere il nome della variabile con il suo valore. È possibile utilizzare un array associativo per raggiungere questo obiettivo.

usa i nomi delle variabili per le chiavi dell'array:

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

Quando vuoi ottenere nomi di variabili, usa array_keys($vars), restituirà una matrice di quei nomi di variabili che sono stati usati nella tua $varsmatrice come chiavi.


Molto più lento dei metodi più comuni per dichiarare le variabili.
David Spector,

0

So che è vecchio e ha già risposto, ma in realtà stavo cercando questo. Sto pubblicando questa risposta per risparmiare un po 'di tempo alle persone affinando alcune delle risposte.

Opzione 1:

$data = array('$FooBar');  

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

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

stampe:

FooBar

Per qualsiasi motivo ti ritrovi in ​​una situazione come questa, in realtà funziona.

.
Opzione 2:

$FooBar = "a string";  

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

Se $FooBarha un valore univoco, stamperà 'FooBar'. Se $FooBarè vuoto o nullo, stamperà il nome della prima stringa vuota o nulla che trova.

Potrebbe essere usato come tale:

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

0

Questo è il modo in cui l'ho fatto

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

uso

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

Nota: alcune versioni di PHP 7 non funzionerà correttamente a causa di un bug in array_searchcon $GLOBALS, ma tutte le altre versioni funzionerà.

Vedi questo https://3v4l.org/UMW7V


-1

Usalo per staccare le variabili utente dal globale per controllare la variabile al momento.

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

@IMSoP A giudicare dall'output di print implode( ' ', array_keys( $GLOBALS ));esso sembra un'ipotesi errata sul numero di globi "predefiniti". Sul mio sistema ci sono sette superglobali: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. E c'è anche argv e argc. Quindi l'offset dovrebbe essere 9. E non ha senso specificare il terzo parametro (lunghezza) poiché il valore predefinito è comunque solo l'esecuzione alla fine dell'array.
Jeff,

-2

Può essere considerato veloce e sporco, ma la mia preferenza personale è quella di utilizzare una funzione / metodo come questo:

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

fondamentalmente crea solo un array associativo contenente un elemento null / vuoto, usando come chiave la variabile per la quale si desidera il nome.

otteniamo quindi il valore di quella chiave usando array_keys e lo restituiamo.

ovviamente questo diventa molto veloce e non sarebbe desiderabile in un ambiente di produzione, ma funziona per il problema presentato.


1
Questo è il valore della variabile, non il nome della variabile. Come indicato altrove, il nome non è portatile oltre i limiti delle funzioni.
Owen Beresford,

3
meno uno perché questa funzione non fa altro che restituire il trim ($ var);
Alexar,

-3

perché dobbiamo usare i globi per ottenere il nome della variabile ... possiamo usare semplicemente come sotto.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }

6
Perché l'OP non conosce il nome della variabile. Se lo facesse, non avrebbe bisogno di una getVarName()funzione. ;-)
FtDRbwLXw6

1
Questo non restituisce il nome di una variabile come stringa, poiché '$variableName'è già una stringa, non una variabile. Se riesci a fare questo trucco getVarName($variableName);, otterrai un voto :)
Daniel W.

-4

Non riesco davvero a vedere il caso d'uso ... Se digiterai print_var_name ($ foobar), cosa c'è di così difficile (e diverso) nel digitare print ("foobar") invece?

Perché anche se dovessi usarlo in una funzione, otterrai il nome locale della variabile ...

In ogni caso, ecco il manuale di riflessione nel caso in cui ci sia qualcosa di cui hai bisogno.


La stampa ("foobar") non gestirà altri var.
Gary Willoughby,

7
Caso d'uso: nel codice sono presenti pochi punti di debug che restituiscono lo stesso valore di dumping. Come fai a sapere quale è stato eseguito per primo? La stampa di un'etichetta è quindi molto utile.
Takeshin

Quindi non hai fatto abbastanza programmazione. La maggior parte delle lingue che ho incontrato hanno un modo per farlo, di solito semplice.
b01,

@ b01 ne ho fatte molte. Sono perfettamente consapevole che ci sono molte lingue che lo consentono, ma questo da solo non significa molto. Molte lingue offrono un modo per fare facilmente goto e ciò non significa che dovresti usarlo per evitare di scrivere un controllo di flusso adeguato. Questo è un caso simile a mio avviso. Non dubito che ci siano casi giustificabili, ed è per questo che mi chiedevo quali fossero i casi d'uso adeguati.
Vinko Vrsalovic,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.