PHP'de değişken adı dize olarak nasıl alınır?


202

Diyelim ki bu PHP kodu var:

$FooBar = "a string";

sonra böyle bir fonksiyona ihtiyacım var:

print_var_name($FooBar);

hangi baskılar:

FooBar

Bunu başarmak için herhangi bir fikir? PHP'de bu mümkün mü?


9
Eğer hata ayıklama dışında herhangi bir şeye ihtiyacınız varsa, çok yanlış bir şey yapıyorsunuz. Kullanım durumunuz nedir?
troelskn

10
İyi soru. Hata ayıklamak için de buna ihtiyacım vardı.
Ocak

17
+1 - Model PHP nesnesinden otomatik olarak XML veya JSON yanıtı oluşturmak için buna ihtiyacım vardı. Nesneyi başka bir adlandırılmış rootName => modelObjectdizinin içine sarmak zorunda kalmak , yanıta gereksiz derinlik katar. Bunun dilin çalışma zamanı yansıtma özelliklerine dönüştürülmesini diliyorum.
Anurag

4
Ayrıca bir günlük fonksiyonu buna ihtiyacım vardı. Aşağıdakileri yapmak istedim: log ($ didTheSystemBlowUp); Günlük dosyasında aşağıdaki gibi görünmek için: $ didTheSystemBlowUp = 'henüz değil, çok yakında';
SeanDowney

4
Ayrıca bu, var_dump () öğesini çağırırken yararlı olabilir, bu nedenle aynı anda birkaç değişkeni çağırdığınızda vardupms çıkışlarını ayırt etmek için var name'i manuel olarak çıkarmamışsınızdır.
PHPst

Yanıtlar:


37

Adını bulmaya çalıştığınız değerle aynı değere sahip bir değişkenin adını bulmak için get_defined_vars () yöntemini kullanabilirsiniz . Açıkçası bu her zaman işe yaramayacaktır, çünkü farklı değişkenler genellikle aynı değerlere sahiptir, ancak bunu yapmayı düşünebilmemin tek yolu budur.

Edit: get_defined_vars () düzgün çalışmıyor gibi görünüyor, $ var fonksiyonun kendisinde kullanıldığından 'var' döndürür. $ GLOBALS çalışıyor gibi gözüktüm.

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

    return false;
}

Düzenleme: net olmak gerekirse, muhtemelen bunu yapmak zorunda olmamalıdır çünkü PHP, bunu yapmak için iyi bir yolu yoktur. Muhtemelen yapmaya çalıştığınız şeyi yapmanın daha iyi yolları vardır.


2
Ahh. Yavaş yavaş ;-) Aynı düşünce, ama bunun yerine $ GLOBALS kullanarak. Yani kimlik karşılaştırması eşit skaler değerler için doğrudur ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel

Aslında şimdi kodumu test ettiğimde, fonksiyonumda kullanıldığından kodum her zaman 'var' döndürdü. Bunun yerine $ GLOBALS kullandığımda, herhangi bir nedenle doğru değişken adını döndürür. Bu yüzden $ GLOBALS kullanmak için yukarıdaki kodu değiştireceğim.
Jeremy Ruten

Evet, fark ettim ama get_defined_vars () yeterli ta oldu.
Gary Willoughby

2
Bu kodun beklendiği gibi davranmayacağı birçok durum vardır.
troelskn

123
Bu kod KORKUNÇ yanlıştır. Değişkeni görmek için VALUE tarafından gönderilen değişkenle aynı olduğunu kontrol etmek çok aptalca bir fikirdir. Sayısız değişken herhangi bir noktada NULL olur. Sayısız 1'e ayarlanmıştır. Bu sadece çılgınca.
Alex Weinstein

49

Bunu da verimli bir şekilde yapmanın bir yolunu düşünemedim ama bunu buldum. Aşağıdaki sınırlı kullanımlar için çalışır.

omuz silkme

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

İşlevin geçtiği argümanı bulduğu fonksiyon olarak adlandırılan çizgiye göre çalışır. Sanırım birden fazla argümanla çalışmak için genişletilebilir, ancak diğerlerinin söylediği gibi, durumu daha iyi açıklayabilirseniz, başka bir çözüm muhtemelen daha iyi çalış.


2
Bu, ancak varName işlevi bulunacak değişkenle aynı dosyada tanımlanmışsa çalışır.
rubo77

1
Burada birkaç şey üzerinde çalışan daha iyi bir uygulama bulabilirsiniz: stackoverflow.com/a/19788805/1069083
rubo77

31

Yaklaşımınızı değiştirmeyi ve değişken değişken adı kullanmayı düşünebilirsiniz.

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

o zaman sadece

print($var_name);

almak

FooBar

İşte Değişken değişkenler hakkındaki PHP kılavuzunun bağlantısı


42
Değişken değişkenleri yoğun olarak kullanan bir sistemle çalıştım. Sizi uyarmama izin verin, çok hızlı kokuyor!
Icode4food

3
çoğu durumda kullanıcı bir var. "fonksiyon debugvar ($ varname)" diye düşünür ve buna "debugvar ('foo')" demeyi düşünür. değişken değişken ile 'foo' alacaklar tanımsızdır.
gcb

sadece ne yaptığınıza bakın. Tam orada örnekte aslında sadece kılavuzu okumak $FooBardeğeri ile bir değişken OLUŞTURMAK a string. Bu korkunç bir imho. değişkene asla $FooBarbir değer atamazsınız, ama oradadır. OUCH
Toskan

20

Hiç kimse bunun a) zor ve b) akılsız olmasının temel nedenlerinden bahsetmemiş gibi görünüyor :

  • "Değişken" yalnızca başka bir şeye işaret eden bir semboldür. PHP, bu içten bir şeye işaret onlar aynı değere sahip olduğundan ya (PHP uygular şey denilen, aslında aynı anda birden fazla değişkenler için kullanılabilecek bir "zval" olarak adlandırılan "kopya üzerinde yazma" böylece $foo = $bargerekmez ek belleği hemen ayırın) veya referans olarak atanmış (veya bir işleve iletilmiş $foo =& $bar) (ör. ). Yani zval'in adı yok.
  • Bir işleve bir parametre ilettiğinizde yeni bir değişken oluşturursunuz (bu bir referans olsa bile). Anonim bir şey aktarabilirsiniz "hello", ancak, bir kez işlevinizin içine, adını verdiğiniz değişken ne olursa olsun. Bu kod ayrılık oldukça esastır: bir işlev değişken itibar etseydim kullanılan çağrılacak, daha çok bir gibi olurdu gotodüzgün ayrı fonksiyonu daha.
  • Global değişkenler genellikle kötü bir fikir olarak kabul edilir. Buradaki örneklerin çoğu, "yansıtmak" istediğiniz değişkenin bulunabileceğini varsayar $GLOBALS, ancak bu yalnızca kodunuzu kötü yapılandırdıysanız ve değişkenler bir işlev veya nesneye dahil edilmediğinde geçerli olacaktır.
  • Değişken isimleri programcıların kodlarını okumalarına yardımcı olmak için vardır. Değişkenleri amaçlarına daha iyi uyacak şekilde yeniden adlandırmak çok yaygın bir yeniden düzenleme uygulamasıdır ve asıl mesele herhangi bir fark yaratmamasıdır.

Şimdi, bunun hata ayıklama isteğini anlıyorum (önerilen kullanımların bazıları bunun ötesine geçmesine rağmen), ancak genelleştirilmiş bir çözüm olarak aslında düşündüğünüz kadar yararlı değil: hata ayıklama işleviniz değişkeninize "$ file denirse ", kodunuzdaki düzinelerce" $ file "değişkeninden herhangi biri veya" $ dosyaadı "olarak adlandırdığınız ancak parametresi" $ file "olarak adlandırılan bir işleve iletilen bir değişken olabilir.

Çok daha kullanışlı bir bilgi, kodunuzda hata ayıklama işlevinin nereden çağrıldığıdır. Bunu düzenleyicinizde hızlı bir şekilde bulabildiğiniz için, hangi değişkeni kendiniz için çıktı aldığınızı görebilir ve hatta tüm ifadeleri tek seferde ona aktarabilirsiniz (örn. debug('$foo + $bar = ' . ($foo + $bar))).

Bunun için hata ayıklama işlevinizin üst kısmında bu snippet'i kullanabilirsiniz:

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

Şimdiden bazı iyi cevaplar var. Yani bu gerçeklik karşısında bile kötümser.
a20

@ a20 Tüm cevapların ne zaman kullanılabilecekleri ve ne zaman kırılacakları konusunda ağır uyarıları vardır; hiçbiri herhangi bir değişkenin ismine basit bir arama değildir, çünkü bu aslında imkansızdır. Bazıları hata ayıklama amaçları için çok korkak yansıma yapar, ki bu iyidir; Ancak, benim görüşüm , sadece satır numarasını çıktılamak ve kaynak hattını kendiniz aramak - veya XDebug gibi etkileşimli bir hata ayıklayıcı kullanmaktan daha iyi olduğunuzu gösterir.
IMSoP

14

Bu tam olarak istediğiniz şeydir - verilen bir varlığın adını yansıtan kullanıma hazır bir "kopyala ve bırak" işlevi:

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

KULLANIM: print_var_name ($ FooBar)

BASKI: FooBar

İPUCU Artık işlevi yeniden adlandırabilirsiniz ve yine de çalışır ve işlevi bir satırda birkaç kez kullanır! @Cliffordlife sayesinde


3
Harika, bunun için teşekkürler. Ben $ pat satırını biraz $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';bu şekilde değiştirdim Bu hata ayıklama işlevinin ne denir umurumda değil, ve tam olarak ne yani yani $ merhaba veya "merhaba" işlevine geçti olsun (Ben geçen değişken için $ maç düştü içerisinde, aynı satırda)
Cliffordlife

1
Fantastik kod parçası! Teşekkürler! Ancak, her durumda işe yaramıyor gibi görünüyor. Ubuntu 18.04 üzerinde php 7.2.19 ile test sonucu: Aynı kod satırında birden çok kez kullanıldığında, bir veya ayrı ifadelerde kullanıldığından bağımsız olarak çalışmaz, çünkü o zaman son değişkenin son değişkeninin adını döndürür hat. Aynı ifadede ancak ayrı satırlarda kullanılıyorsa çalışır. Çalıştığı farklı satırlarda farklı ifadelerde kullanılır.
Matty

1
Ayrıca bu işlev "var_dump" olmadan tek bir satırda olmalıdır - kombinasyon print_var_name, echo, var_dumpgönderme çıkışı ile$variable); echo ' '; var_dump($variable
BG Bruno

13

PHP.net üzerindeki Lucas, bir değişken olup olmadığını kontrol etmek için güvenilir bir yol sağlamıştır. Örneğinde, değişkenlerin genel değişken dizisinin (veya kapsamlandırılmış dizisinin) bir kopyasını yineler, değeri rastgele oluşturulan bir değere değiştirir ve kopyalanan dizide oluşturulan değeri denetler.

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

O zaman dene:

$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

PHP.net'teki yayınını kontrol ettiğinizden emin olun: http://php.net/manual/en/language.variables.php


Geçerli kapsamı dizi biçiminde nasıl elde edersiniz?
Sebastián Grignoli

Güzel! Benim için sadece eksik break;foreach eşit olduğunda + fonksiyon içinde tanımlanırsa otomatik olarak var_name almak için kullanılabilir temel yapı yaptım. Sık sık Kopyala & Yapıştır veya geliştirmek için daha iyi bir fikriniz varsa kullanınvariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2

Bu muhtemelen işi yapmanın en hızlı ve en temiz yoludur, hata ayıklama muhtemelen performans sorunlarını içerir. İşlev kesintisiz olarak atamak yerine doğrudan foreach döngüsüne dönmelidir. GLOBALS büyük olabilir, bu da bir performans iyileştirmesi olabilir.
John

13

Hata ayıklama nedenleriyle bir inceleme işlevi yaptım. Steroidlerde print_r () gibidir, Krumo'ya çok benzer, ancak nesneler üzerinde biraz daha etkilidir. Var ad algılamasını eklemek istedim ve Nick Presta'nın bu sayfadaki gönderisinden esinlenerek çıktı. Yalnızca değişken adları değil, bağımsız değişken olarak iletilen herhangi bir ifadeyi algılar.

Bu yalnızca iletilen ifadeyi algılayan sarmalayıcı işlevidir. Vakaların çoğunda çalışır. İşlevi aynı kod satırında bir kereden fazla çağırırsanız çalışmaz.

Bu iyi çalışıyor: ölmek ( inceleyin ($ This-> GetUser () -> hasCredential ( "delete")) );

inspect (), iletilen ifadeyi algılayacak işlevdir.

Şunu elde ediyoruz: $ 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);

}

İşte müfettiş işlevinin (ve benim dInspect sınıfım) bir örneği:

http://inspect.ip1.cc

Metinler bu sayfada İspanyolca, ancak kod özlü ve anlaşılması gerçekten kolay.


1
errrm, NuSphare hata ayıklayıcısının kurulu olmasına güvenmiyor mu?
Mawg diyor Monica

Orada bu kodun basitleştirilmiş bir sürümünü yayınladım. Ayrıca bu cevabı değiştirdim. Şimdi her PHP5 uygulamasında çalışmalıdır.
Sebastián Grignoli

Bu tür yaratıcılık, insanların "yapılamıyor" ya da "mümkün değil" dediğini her gördüğümde gülümsememdir, ki bu durumda Rasmus'un kendisi bile. Sebastián ve bu cevaba katkıda bulunmuş olabilecek herkes için şeref.
Gece Baykuşu

1
Teşekkürler Gece Baykuş, ama bunun kurşun geçirmez olmadığı konusunda ısrar ediyorum (cevap belirttiği gibi, benim "inspect ()" fonksiyonum tek bir satırda birden fazla çağrılırsa başarısız olacaktır!). Bunu asla üretimde kullanmam. Yalnızca üretim sunucusuna asla ulaşmaması gereken bir hata ayıklama denetçisi işlevi içindir.
Sebastián Grignoli

7

itibaren php.net

@Alexandre - kısa çözüm

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

@Lucas - kullanım

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

Birçok yanıt, bunun yararlılığını sorgulamaktadır. Bununla birlikte, bir değişken için referans almak çok faydalı olabilir. Özellikle nesneler ve $ $ olan durumlarda . Çözümüm nesnelerle ve özellik tanımlı nesneler olarak da çalışır:

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

Yukarıdakilere örnek:

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

Birçok değişken için yukarıdaki yanıtlardan uyarlanmış, iyi performansla, birçokları için sadece bir $ GLOBALS tarama

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

Değişken değiştirilebilir ise, hangi değişkenin kullanılacağını belirleyen bir yerde mantığınız olmalıdır . Tek yapmanız gereken değişken ismini koymak$variable diğer her şeyi yaparken bu mantığın .

Sanırım hepimiz bunun için neye ihtiyacınız olduğunu anlamakta zorlanıyoruz. Örnek kod veya aslında çalıştığınız şeyin bir açıklama yapmak kudreti yardıma, ama sana şeklin şüpheli yolu bu overthinking.


1

Aslında bunun için geçerli bir kullanım durumum var.

Bir işlev cacheVariable ($ var) var (Tamam, bir işlev önbelleği var ($ anahtar, $ değeri), ama belirtildiği gibi bir işlevi var istiyorum).

Amaç:

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

...

// another session

...

$myColour = getCachedVariable('colour');

İle denedim

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
}

Ben de denedim

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

Ama bu da başarısız oluyor ... :(

Tabii, önbellek yapmaya devam edebilirim ('renk', $ renk), ama tembelim, biliyorsun ...;)

Yani, istediğim bir işleve geçirildiği gibi bir değişken ORİJİNAL adını alır bir işlevdir. Fonksiyonun içinde göründüğü gibi bilmem mümkün değil. Yukarıdaki ikinci örnekte referans olarak get_defined_vars () iletmek bana yardımcı oldu (bu fikir için Jean-Jacques Guegan'a teşekkürler). İkinci işlev çalışmaya başladı, ancak yine de yalnızca yerel değişkeni döndürmeye devam etti ('renk' değil, 'değişken').

Ben get_func_args () ve get_func_arg (), $ {} - yapıları ve key () kombine kullanmak için henüz denemedim, ama aynı zamanda başarısız olacağını varsayıyorum.


1
En temel sorun, değerleri değişkenlere değil fonksiyonlara geçirmenizdir . Değişkenler geçicidir ve kapsamlarına özgüdür. Değişken adı genellikle değeri önbelleğe almak istediğiniz anahtar olmayabilir ve genellikle yine de farklı bir adlandırılmış değişkene (örneğin örneğinizde olduğu gibi) geri yüklersiniz. Değişkeni hatırlamak için anahtarın adını tekrarlamak için gerçekten çok tembelseniz, kullanın cacheVariable(compact('color')).
deceze

1

Bu bende var:

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

Bunu tercih ederim:

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

Mevcut işlev, kırmızı anahatlı sarı bir kutu görüntüler ve her değişkeni ada ve değere göre gösterir. Dizi çözümü çalışır, ancak gerektiğinde yazmak için biraz kıvrıktır.

Bu benim kullanım durumum ve evet, hata ayıklama ile ilgili. Aksi takdirde kullanımını sorgulayanlara katılıyorum.


1

İşte benim çözüm dayalı Jeremy Ruten

class DebugHelper {

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

onu kullanarak

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

0

Neden basit bir fonksiyon oluşturup anlatmıyorsunuz?

/**
 * 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

Bunu arıyordum ama sadece adı geçmeye karar verdim, genellikle panoda adı zaten var.

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

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

0

Bunu başarmak için compact () kullanabilirsiniz.

$FooBar = "a string";

$newArray = compact('FooBar');

Bu, anahtar olarak değişken adıyla ilişkilendirilebilir bir dizi oluşturur. Daha sonra, ihtiyacınız olan anahtar adını kullanarak dizi arasında geçiş yapabilirsiniz.

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

2
Güzel ama kullanmak için değişkenin adını bilmeniz gerekir. OP, değişken adını programsal olarak belirlemek istiyor.
bir kodlayıcı

0

Değişken adını değeriyle bilmek istediğinizi düşünüyorum. Bunu başarmak için ilişkilendirilebilir bir dizi kullanabilirsiniz.

dizi anahtarları için değişken adları kullanın:

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

Değişken adları almak istediğinizde, kullanın array_keys($vars), $varsdizinizde anahtar olarak kullanılan değişken adlarının bir dizisini döndürür .


Değişkenleri bildirmenin daha olağan yöntemlerinden çok daha yavaş.
David Spector

0

Bunun eski olduğunu ve zaten cevaplandığını biliyorum ama aslında bunu arıyordum. Bu cevabı, bazı cevapları iyileştirmek için biraz zaman kazanmak için gönderiyorum.

Seçenek 1:

$data = array('$FooBar');  

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

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

Baskılar:

filanca

Herhangi bir nedenle kendinizi böyle bir durumda bulursanız, aslında işe yarıyor.

.
Seçenek 2:

$FooBar = "a string";  

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

$FooBarBenzersiz bir değere sahipse , 'FooBar' yazdıracaktır. $FooBarBoş veya null olursa , bulduğu ilk boş veya null dizenin adını yazdırır.

Bu şekilde kullanılabilir:

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

0

Ben böyle yaptım

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

kullanım

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

Not: Bazı PHP 7 sürümleri içinde bir hata nedeniyle düzgün çalışmaz array_searchile $GLOBALSancak tüm diğer sürümleri çalışacaktır.

Bkz. Https://3v4l.org/UMW7V


-1

Şu anda değişkeni kontrol etmek için kullanıcı değişkenlerini globalden ayırmak için bunu kullanın.

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 Çıktılarına bakılırsa print implode( ' ', array_keys( $GLOBALS ));, "varsayılan" küresellerin sayısı hakkında yanlış bir varsayım gibi görünüyor. Sistemimde yedi süper küresel var: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Ayrıca argv ve argc de var. Bu nedenle, ofset 9 olmalıdır. Ve varsayılan, yine de dizinin sonuna kadar çalışmak olduğundan üçüncü parametreyi (uzunluk) belirtmenin bir anlamı yoktur.
Jeff

-2

Hızlı ve kirli olarak kabul edilebilir, ancak kendi kişisel tercihim böyle bir işlev / yöntem kullanmaktır:

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

temelde sadece adını istediğiniz değişkeni bir anahtar olarak kullanarak bir null / boş eleman içeren bir ilişkisel dizi oluşturur.

sonra dizi_anahtarlarını kullanarak o anahtarın değerini alırız ve geri veririz.

Açıkçası bu çok çabuk dağınık hale gelir ve bir üretim ortamında arzu edilmez, ancak sunulan sorun için işe yarar.


1
Bu, değişkenin adıdır, değişkenin adı değildir. Başka bir yerde belirtildiği gibi, isim fonksiyon sınırları boyunca taşınabilir değildir.
Owen Beresford

3
eksi bir, çünkü bu işlev tam anlamıyla trim döndürmekten başka bir şey yapmaz ($ var);
Alexar

-3

neden değişken ismi almak için globalleri kullanmak zorundayız ... aşağıdaki gibi kullanabiliriz.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

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

6
Çünkü OP değişken adını bilmiyor. Eğer yapsaydı, bir getVarName()işleve ihtiyacı olmazdı . ;-)
FtDRbwLXw6

1
Bu, değişkenin adını dize olarak döndürmez, çünkü '$variableName'zaten bir dize, bir değişken değildir. Bu numarayı yapabiliyorsanız getVarName($variableName);, bir oylama yapabilirsiniz :)
Daniel W.

-4

Gerçekten kullanım durumunu göremiyorum ... print_var_name ($ foobar) yazacaksanız bunun yerine print ("foobar") yazmanın ne kadar zor (ve farklı) olduğunu?

Çünkü bunu bir işlevde kullansanız bile, değişkenin yerel adını alırsınız ...

Her durumda, burada ihtiyacınız olan bir şey olması durumunda yansıma kılavuzu .


Yazdır ("foobar") diğer değişkenleri işlemez.
Gary Willoughby

7
Büyük / küçük harf kullanımı: kodda aynı değeri boşaltma döndüren birkaç hata ayıklama noktanız var. Hangisinin önce idam edildiğini nasıl anlarsınız? Bir etiket basmak çok faydalıdır.
Mayıs

O zaman yeterince programlama yapmadınız. Karşılaştığım çoğu dilin bunu yapmanın bir yolu var, genellikle basit.
b01

@ b01 Çok şey yaptım. Buna izin veren birçok dil olduğunu çok iyi biliyorum, ama bu tek başına fazla bir şey ifade etmiyor. Birçok dil, kolayca goto yapmanın bir yolunu sunar ve bu, uygun akış kontrolü yazmaktan kaçınmak için kullanmanız gerektiği anlamına gelmez. Bence bu da benzer bir durum. Haklı davalar olduğundan şüphe etmiyorum ve bu yüzden bunun için uygun kullanım durumlarını merak ediyordum.
Vinko Vrsalovic
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.