Bagaimana cara mendapatkan nama variabel sebagai string di PHP?

201

Katakanlah saya punya kode PHP ini:

$FooBar = "a string";

saya kemudian membutuhkan fungsi seperti ini:

print_var_name($FooBar);

yang mencetak:

FooBar

Ada Gagasan bagaimana mencapai ini? Apakah ini mungkin di PHP?

Gary Willoughby
sumber
9
Jika Anda membutuhkan ini selain debug, Anda melakukan kesalahan besar. Apa kasus penggunaan Anda?
troelskn
10
Pertanyaan bagus. Saya membutuhkan hal yang sama untuk debugging.
takeshin
17
+1 - Saya memerlukan ini untuk respons XML atau JSON yang menghasilkan otomatis dari objek model PHP. Harus membungkus objek di dalam rootName => modelObjectarray bernama lain hanya menambahkan kedalaman yang tidak perlu ke respons. Berharap ini dimasukkan ke dalam kemampuan refleksi runtime bahasa.
Anurag
4
Saya juga punya kebutuhan untuk ini dalam fungsi logging. Saya ingin dapat melakukan hal berikut: log ($ didTheSystemBlowUp); Muncul di file log seperti: $ didTheSystemBlowUp = 'belum, tetapi segera';
SeanDowney
4
Juga ini dapat berguna saat memanggil var_dump () jadi ketika Anda memanggil pada waktu yang sama pada beberapa variabel Anda belum secara manual menampilkan nama var untuk membedakan antara keluaran vardupms.
PHPst

Jawaban:

37

Anda bisa menggunakan get_defined_vars () untuk menemukan nama variabel yang memiliki nilai yang sama dengan yang Anda coba temukan nama. Jelas ini tidak akan selalu berhasil, karena variabel yang berbeda sering memiliki nilai yang sama, tetapi itu satu-satunya cara yang dapat saya pikirkan untuk melakukan ini.

Sunting: get_defined_vars () tampaknya tidak berfungsi dengan benar, ia mengembalikan 'var' karena $ var digunakan dalam fungsi itu sendiri. $ GLOBAL tampaknya berhasil, jadi saya telah mengubahnya.

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

    return false;
}

Sunting: agar jelas, tidak ada cara yang baik untuk melakukan ini di PHP, yang mungkin karena Anda tidak harus melakukannya. Mungkin ada cara yang lebih baik untuk melakukan apa yang Anda coba lakukan.

Jeremy Ruten
sumber
2
Ahh. Berkunjung ke lambat ;-) Berpikir sama, tetapi menggunakan $ GLOBALS sebagai gantinya. Jadi perbandingan identitas menghasilkan true untuk sama dengan nilai skalar ($ a = 'foo'; $ b = 'foo'; nyatakan ($ a === $ b);)?
Argelbargel
Sebenarnya sekarang saya sudah menguji kode saya, kode saya selalu mengembalikan 'var' karena sedang digunakan dalam fungsi. Ketika saya menggunakan $ GLOBALS sebagai gantinya, ia mengembalikan nama variabel yang benar untuk beberapa alasan. Jadi saya akan mengubah kode di atas untuk menggunakan $ GLOBALS.
Jeremy Ruten
Yup, saya sadar tapi get_defined_vars () sudah cukup ta.
Gary Willoughby
2
Ada banyak kasus di mana kode ini tidak berlaku seperti yang diharapkan.
troelskn
122
Kode ini sangat salah. Memeriksa untuk melihat apakah variabelnya sama dengan yang dikirim oleh VALUE adalah ide yang sangat bodoh. Bermacam-macam variabel NULL pada titik tertentu. Myriads diatur ke 1. Ini hanya gila.
Alex Weinstein
49

Saya tidak bisa memikirkan cara untuk melakukan ini dengan efisien, tetapi saya menemukan ini. Ini berfungsi, untuk penggunaan terbatas di bawah.

mengangkat bahu

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

Ini bekerja berdasarkan pada baris yang disebut fungsi, di mana ia menemukan argumen yang Anda berikan. Saya kira itu bisa diperluas untuk bekerja dengan beberapa argumen tetapi, seperti yang lain katakan, jika Anda bisa menjelaskan situasinya dengan lebih baik, solusi lain mungkin akan bekerja lebih baik.

Nick Presta
sumber
2
Ini berfungsi, tetapi hanya jika fungsi varName didefinisikan dalam file yang sama dengan variabel yang akan ditemukan.
rubo77
1
Di sini Anda menemukan implementasi yang lebih baik yang berfungsi pada beberapa di
antaranya
31

Anda mungkin mempertimbangkan untuk mengubah pendekatan Anda dan menggunakan nama variabel variabel?

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

maka kamu bisa saja

print($var_name);

mendapatkan

FooBar

Berikut tautan ke manual PHP tentang variabel Variabel


sumber
42
Saya telah bekerja dengan sistem yang menggunakan variabel variabel secara ekstensif. Biarkan saya memperingatkan Anda, itu menjadi sangat bau sangat cepat!
Icode4food
3
sebagian besar kasus pengguna ingin mendapatkan nama dan nilai var. pikirkan "function debugvar ($ varname)" dan dia bermaksud menyebutnya "debugvar ('foo')" sehingga debug akan menampilkan "foo = 123". dengan variabel variabel mereka akan mendapatkan 'foo' tidak terdefinisi.
gcb
lihat saja apa yang sebenarnya Anda lakukan. Di sana, dalam contoh Anda, Anda sebenarnya BUAT variabel $FooBardengan nilai a stringhanya membaca manual Anda. Ini imho yang mengerikan. Anda tidak pernah menetapkan nilai variabel $FooBar, tetapi itu ada di sana. OUCH
Toskan
20

Tidak seorang pun tampaknya telah menyebutkan alasan mendasar mengapa ini a) keras dan b) tidak bijaksana:

  • "Variabel" hanyalah simbol yang menunjuk pada sesuatu yang lain. Dalam PHP, secara internal menunjuk ke sesuatu yang disebut "zval", yang sebenarnya dapat digunakan untuk beberapa variabel secara bersamaan, baik karena mereka memiliki nilai yang sama (PHP mengimplementasikan sesuatu yang disebut "copy-on-write" sehingga $foo = $bartidak perlu mengalokasikan memori tambahan langsung) atau karena mereka telah ditetapkan (atau diteruskan ke suatu fungsi) dengan referensi (misalnya $foo =& $bar). Jadi zval tidak memiliki nama.
  • Ketika Anda melewatkan parameter ke suatu fungsi Anda membuat variabel baru (bahkan jika itu referensi). Anda dapat melewatkan sesuatu yang anonim, seperti "hello", tetapi begitu berada di dalam fungsi Anda, variabel apa pun yang Anda beri nama. Ini cukup mendasar untuk pemisahan kode: jika suatu fungsi bergantung pada apa variabel yang dulu dipanggil, itu akan lebih seperti sebuah gotodaripada fungsi yang terpisah dengan benar.
  • Variabel global umumnya dianggap sebagai ide yang buruk. Banyak contoh di sini mengasumsikan bahwa variabel yang ingin Anda "refleksikan" dapat ditemukan $GLOBALS, tetapi ini hanya akan benar jika Anda telah menyusun kode Anda dengan buruk dan variabel tidak dibatasi untuk beberapa fungsi atau objek.
  • Ada nama variabel untuk membantu programmer membaca kode mereka. Mengganti nama variabel agar lebih sesuai dengan tujuannya adalah praktik refactoring yang sangat umum, dan intinya adalah bahwa itu tidak membuat perbedaan.

Sekarang, saya memahami keinginan untuk melakukan debugging (walaupun beberapa penggunaan yang diusulkan jauh melampaui itu), tetapi sebagai solusi umum itu sebenarnya tidak membantu seperti yang Anda kira: jika fungsi debug Anda mengatakan variabel Anda disebut "$ file ", itu masih bisa salah satu dari banyak variabel" $ file "dalam kode Anda, atau variabel yang Anda panggil" $ nama file "tetapi meneruskan ke fungsi yang parameternya disebut" $ file ".

Sepotong informasi yang jauh lebih berguna adalah di mana dalam kode Anda fungsi debug dipanggil. Karena Anda dapat dengan cepat menemukan ini di editor Anda, Anda dapat melihat variabel mana yang Anda hasilkan sendiri, dan bahkan dapat meneruskan seluruh ekspresi ke dalamnya dalam satu kali jalan (mis debug('$foo + $bar = ' . ($foo + $bar)).).

Untuk itu, Anda dapat menggunakan potongan ini di bagian atas fungsi debug Anda:

$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];
IMSoP
sumber
Sudah ada beberapa jawaban bagus. Jadi ini hanya pesimistis bahkan dalam menghadapi kenyataan.
a20
@ a20 Semua jawaban memiliki peringatan berat tentang kapan mereka dapat digunakan, dan kapan mereka akan pecah; tidak ada pencarian sederhana dari variabel apa pun ke namanya, karena itu sebenarnya tidak mungkin. Beberapa melakukan banyak refleksi funky untuk keperluan debugging, yang baik-baik saja; Namun, pendapat saya berpendapat bahwa Anda lebih baik hanya mengeluarkan nomor baris dan mencari sendiri baris sumber - atau menggunakan debugger interaktif seperti XDebug.
IMSoP
14

Ini persis yang Anda inginkan - fungsi siap pakai "salin dan jatuhkan" yang menggemakan nama var yang diberikan:

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)

PRINT: FooBar

PETUNJUK Sekarang Anda dapat mengubah nama fungsi dan itu masih akan berfungsi dan juga menggunakan fungsi beberapa kali dalam satu baris! Terima kasih kepada @Cliffordlife

adilbo
sumber
3
Keren, terima kasih untuk ini. Saya memodifikasi garis $ pat sedikit dengan $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';cara ini saya tidak peduli apa fungsi debug ini disebut, dan saya mendapatkan apa yang diteruskan ke dalam fungsi yaitu $ hello, atau "hello" (saya menjatuhkan $ match untuk variabel yang dilewati) di, di baris yang sama)
Cliffordlife
1
Sepotong kode fantastis! Terima kasih! Namun, sepertinya tidak berfungsi dalam semua kasus. Hasil pengujian di ubuntu 18.04 saya dengan php 7.2.19: Tidak berfungsi ketika digunakan beberapa kali pada baris kode yang sama, terlepas dari apakah itu digunakan dalam satu atau ekspresi yang terpisah, karena dengan demikian ia mengembalikan nama variabel terakhir dari baris. Jika digunakan dalam ekspresi yang sama tetapi pada baris yang terpisah itu berfungsi. Digunakan dalam ekspresi berbeda pada garis yang berbeda.
Matty
1
juga fungsi itu harus dalam satu baris tanpa "var_dump" - dengan kombinasi print_var_name, echo, var_dumpsend output$variable); echo ' '; var_dump($variable
BG Bruno
13

Lucas di PHP.net menyediakan cara yang andal untuk memeriksa apakah ada variabel. Dalam contohnya, ia mengulangi melalui salinan array variabel global (atau array tercakup) variabel, mengubah nilai menjadi nilai yang dihasilkan secara acak, dan memeriksa nilai yang dihasilkan dalam array yang disalin.

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

Lalu coba:

$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

Pastikan untuk memeriksa posnya di PHP.net: http://php.net/manual/en/language.variables.php

Tukang
sumber
Bagaimana Anda mendapatkan ruang lingkup saat ini dalam bentuk array?
Sebastián Grignoli
Bagus! Bagi saya hanya hilang adalah break;ketika ditemukan sama dalam foreach + saya melakukan struktur dasar yang dapat digunakan untuk secara otomatis mendapatkan var_name juga jika didefinisikan dalam fungsi. Jika Anda sering Salin & Tempel atau punya ide yang lebih baik untuk memperbaikinya, gunakanvariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2
Ini mungkin cara tercepat dan terbersih untuk melakukan pekerjaan itu, debugging kemungkinan mencakup masalah kinerja. Fungsi harus kembali secara langsung di loop foreach alih-alih hanya menetapkan tanpa gangguan. Mengingat GLOBAL bisa menjadi besar sehingga bisa menjadi peningkatan kinerja yang cukup.
John
13

Saya membuat fungsi inspeksi untuk alasan debugging. Ini seperti print_r () pada steroid, seperti Krumo tetapi sedikit lebih efektif pada objek. Saya ingin menambahkan deteksi nama var dan keluar dengan ini, terinspirasi oleh posting Nick Presta di halaman ini. Itu mendeteksi ekspresi yang diberikan sebagai argumen, tidak hanya nama variabel.

Ini hanya fungsi pembungkus yang mendeteksi ekspresi yang dikirimkan. Bekerja pada sebagian besar kasus. Ini tidak akan berfungsi jika Anda memanggil fungsi lebih dari satu kali pada baris kode yang sama.

Ini berfungsi dengan baik: mati ( periksa$ this-> getUser () -> hasCredential ("delete")) );

inspect () adalah fungsi yang akan mendeteksi ekspresi yang dikirimkan.

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

}

Berikut adalah contoh fungsi inspektur (dan kelas dInspect saya) dalam aksi:

http://inspect.ip1.cc

Teks dalam bahasa Spanyol di halaman itu, tetapi kode singkat dan sangat mudah dimengerti.

Sebastián Grignoli
sumber
1
errrm, bukankah itu bergantung pada Anda memiliki NuSphare debugger diinstal?
Mawg mengatakan mengembalikan Monica
Saya memposting versi sederhana dari kode ini di sana. Saya juga memodifikasi jawaban ini. Itu harus dijalankan pada setiap implementasi PHP5 sekarang.
Sebastián Grignoli
Kecerdikan seperti ini adalah mengapa saya tersenyum setiap kali saya melihat orang mengatakan "tidak dapat dilakukan" atau "tidak mungkin", yang termasuk bahkan Rasmus sendiri dalam kasus ini. Kudos to Sebastián dan siapa pun yang mungkin berkontribusi pada jawaban ini.
Night Owl
1
Terima kasih Night Owl, tapi saya bersikeras bahwa ini bukan bukti peluru (sebagai jawabannya menyatakan, itu akan gagal jika fungsi "inspect ()" saya dipanggil lebih dari sekali dalam satu baris!). Saya tidak akan pernah menggunakan ini dalam produksi. Ini hanya untuk fungsi inspektur debugging yang seharusnya tidak pernah mencapai server produksi.
Sebastián Grignoli
7

Dari php.net

@Alexandre - solusi singkat

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

@Lucas - penggunaan

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

sumber
4

Banyak balasan mempertanyakan kegunaan dari ini. Namun, mendapatkan referensi untuk suatu variabel bisa sangat berguna. Terutama dalam kasus dengan objek dan $ this . Solusi saya berfungsi dengan objek, dan sebagai objek yang didefinisikan properti juga:

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

Contoh untuk yang di atas:

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
sumber
2

Diadaptasi dari jawaban di atas untuk banyak variabel, dengan kinerja yang baik, hanya satu pemindaian $ GLOBAL untuk banyak variabel

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
        )

)
pengguna1933288
sumber
1

Jika variabel tersebut dapat dipertukarkan, Anda harus memiliki logika di suatu tempat yang menentukan variabel mana yang akan digunakan. Yang perlu Anda lakukan adalah memasukkan nama variabel di $variabledalam logika itu saat Anda melakukan yang lainnya.

Saya pikir kita semua kesulitan memahami untuk apa Anda membutuhkannya. Kode contoh atau penjelasan tentang apa yang sebenarnya Anda coba lakukan mungkin bisa membantu, tapi saya curiga Anda memang berpikir terlalu jauh .

ceejayoz
sumber
1

Saya sebenarnya memiliki kasus penggunaan yang valid untuk ini.

Saya memiliki fungsi cacheVariable ($ var) (ok, saya memiliki fungsi cache ($ key, $ value), tetapi saya ingin memiliki fungsi seperti yang disebutkan).

Tujuannya adalah untuk melakukan:

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

...

// another session

...

$myColour = getCachedVariable('colour');

Saya sudah mencoba

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
}

Saya juga sudah mencoba

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

Tapi ini juga gagal ... :(

Tentu, saya bisa terus melakukan cache ('warna', $ warna), tapi saya malas, Anda tahu ...;)

Jadi, yang saya inginkan adalah fungsi yang mendapatkan nama ASLI dari variabel, karena diteruskan ke fungsi. Di dalam fungsi itu tidak mungkin saya bisa tahu itu, seperti yang terlihat. Melewati get_defined_vars () dengan referensi dalam contoh kedua di atas membantu saya (Terima kasih kepada Jean-Jacques Guegan untuk ide itu) agak. Fungsi terakhir mulai bekerja, tetapi masih tetap mengembalikan variabel lokal ('variabel', bukan 'warna').

Saya belum mencoba menggunakan get_func_args () dan get_func_arg (), $ {} - konstruk dan key () digabungkan, tetapi saya kira itu akan gagal juga.

Aron Cederholm
sumber
1
Masalah yang sangat mendasar adalah bahwa Anda memberikan nilai ke fungsi, bukan variabel . Variabel bersifat sementara dan khusus untuk cakupannya. Seringkali nama variabel mungkin bukan kunci yang Anda inginkan untuk menyimpan nilai di bawahnya, dan sering kali Anda akan mengembalikannya ke variabel dengan nama berbeda (seperti yang Anda lakukan dalam contoh Anda). Jika Anda benar-benar malas untuk mengulangi nama kunci untuk mengingat variabel dengan, gunakan cacheVariable(compact('color')).
deceze
1

Aku punya ini:

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

Saya lebih suka ini:

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

Fungsi yang ada menampilkan kotak kuning dengan garis merah dan menunjukkan masing-masing variabel berdasarkan nama dan nilai. Solusi array berfungsi tetapi sedikit berbelit-belit untuk mengetik ketika dibutuhkan.

Itu kasus penggunaan saya dan ya, itu ada hubungannya dengan debugging. Saya setuju dengan mereka yang mempertanyakan penggunaannya sebaliknya.

Will Fastie
sumber
1

Inilah solusi saya berdasarkan Jeremy Ruten

class DebugHelper {

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

menggunakannya

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

Mengapa Anda tidak membangun fungsi sederhana dan MENGATAKANnya?

/**
 * 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' );
Orang tua
sumber
0

Saya mencari ini tetapi hanya memutuskan untuk memasukkan nama, saya biasanya memiliki nama di clipboard.

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

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

Anda bisa menggunakan compact () untuk mencapai ini.

$FooBar = "a string";

$newArray = compact('FooBar');

Ini akan membuat array asosiatif dengan nama variabel sebagai kunci. Anda kemudian dapat mengulang melalui array menggunakan nama kunci di mana Anda membutuhkannya.

foreach($newarray as $key => $value) {
    echo $key;
}
Budove
sumber
2
Keren tapi Anda harus tahu nama variabel untuk menggunakannya. OP sedang mencari untuk menentukan nama variabel secara terprogram.
seorang coder
0

Saya pikir Anda ingin tahu nama variabel dengan nilainya. Anda dapat menggunakan array asosiatif untuk mencapai ini.

gunakan nama variabel untuk kunci array:

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

Ketika Anda ingin mendapatkan nama variabel, gunakan array_keys($vars), itu akan mengembalikan array nama-nama variabel yang digunakan dalam $varsarray Anda sebagai kuncinya.

Janaka R Rajapaksha
sumber
Jauh lebih lambat daripada metode yang biasa digunakan untuk mendeklarasikan variabel.
David Spector
0

Saya tahu ini sudah tua dan sudah dijawab tetapi saya sebenarnya mencari ini. Saya memposting jawaban ini untuk menghemat sedikit waktu bagi orang untuk memperbaiki beberapa jawaban.

Pilihan 1:

$data = array('$FooBar');  

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

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

Cetakan:

FooBar

Untuk alasan apa pun Anda akan menemukan diri Anda dalam situasi seperti ini, itu benar-benar berhasil.

.
Pilihan 2:

$FooBar = "a string";  

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

Jika $FooBarmemiliki nilai unik, itu akan mencetak 'FooBar'. Jika$FooBar kosong atau nol itu akan mencetak nama string kosong atau nol pertama yang ditemukannya.

Itu bisa digunakan seperti itu:

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

Ini adalah cara saya melakukannya

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

Pemakaian

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

Catatan: beberapa PHP 7 versi tidak akan berfungsi karena bug dalam array_searchdengan $GLOBALS, namun semua versi lain akan bekerja.

Lihat ini https://3v4l.org/UMW7V

Hujan
sumber
-1

Gunakan ini untuk melepaskan variabel pengguna dari global untuk memeriksa variabel saat ini.

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
sumber
@IMSoP Dilihat dari outputnya print implode( ' ', array_keys( $GLOBALS ));terlihat seperti asumsi keliru tentang jumlah global "default". Di sistem saya ada tujuh superglobals: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Dan ada juga argv dan argc. Jadi offsetnya harus 9. Dan tidak ada gunanya menentukan parameter ketiga (panjang) karena standarnya hanya menjalankan ke akhir array.
Jeff
-2

Ini mungkin dianggap cepat dan kotor, tetapi preferensi pribadi saya adalah menggunakan fungsi / metode seperti ini:

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

pada dasarnya itu hanya membuat array asosiatif yang mengandung satu elemen kosong / kosong, menggunakan sebagai kunci variabel yang Anda inginkan namanya.

kita kemudian mendapatkan nilai kunci itu menggunakan array_keys dan mengembalikannya.

jelas ini menjadi cepat berantakan dan tidak diinginkan di lingkungan produksi, tetapi berfungsi untuk masalah yang disajikan.

pengguna3344253
sumber
1
Itulah nilai variabel, bukan nama variabel. Seperti yang ditunjukkan di tempat lain, namanya tidak portabel di seluruh batas fungsi.
Owen Beresford
3
minus satu karena fungsi ini secara harfiah tidak melakukan apa-apa selain mengembalikan trim ($ var);
Alexar
-3

mengapa kita harus menggunakan global untuk mendapatkan nama variabel ... bisa kita gunakan seperti di bawah ini.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }
Ajaxmint
sumber
6
Karena OP tidak tahu nama variabelnya. Jika dia melakukannya, dia tidak akan membutuhkan getVarName()fungsi. ;-)
FtDRbwLXw6
1
Ini tidak mengembalikan nama variabel sebagai string, karena '$variableName'sudah menjadi string, bukan variabel. Jika Anda dapat melakukan trik ini dengan getVarName($variableName);, Anda mendapatkan upvote :)
Daniel W.
-4

Saya benar-benar gagal melihat use case ... Jika Anda akan mengetik print_var_name ($ foobar) apa yang sulit (dan berbeda) tentang mengetikkan print ("foobar")?

Karena bahkan jika Anda menggunakan ini dalam suatu fungsi, Anda akan mendapatkan nama lokal dari variabel ...

Dalam kasus apa pun, inilah panduan refleksi untuk berjaga-jaga seandainya ada sesuatu yang Anda butuhkan di sana.

Vinko Vrsalovic
sumber
Cetak ("foobar") tidak akan menangani vars lainnya.
Gary Willoughby
7
Use case: Anda memiliki beberapa titik debug dalam kode yang mengembalikan dumping dengan nilai yang sama. Bagaimana Anda tahu yang mana yang dieksekusi lebih dulu? Mencetak label sangat bermanfaat.
takeshin
Maka Anda belum cukup melakukan pemrograman. Sebagian besar bahasa yang saya temui memiliki beberapa cara untuk melakukan ini, biasanya sederhana.
B01
@ B01 Saya sudah melakukan banyak hal. Saya sangat menyadari ada banyak bahasa yang memungkinkan ini, tetapi itu dengan sendirinya tidak banyak berarti. Banyak bahasa menawarkan cara untuk melakukan goto dengan mudah dan itu tidak berarti Anda harus menggunakannya untuk menghindari penulisan kontrol aliran yang tepat. Ini adalah kasus serupa dalam pandangan saya. Saya tidak ragu ada kasus yang dapat dibenarkan, dan itulah sebabnya saya bertanya-tanya tentang kasus penggunaan yang tepat untuk itu.
Vinko Vrsalovic