PHPで変数名を文字列として取得するにはどうすればよいですか?


201

このPHPコードがあるとしましょう:

$FooBar = "a string";

次に、次のような関数が必要です。

print_var_name($FooBar);

印刷する:

FooBar

これを達成する方法はありますか?これはPHPでも可能ですか?


9
デバッグ以外にこれが必要な場合は、深刻な問題が発生しています。あなたのユースケースは何ですか?
troelskn 2008年

10
良い質問。デバッグにも同じものが必要でした。
takeshin

17
+1-モデルのPHPオブジェクトからXMLまたはJSON応答を自動生成するためにこれが必要でした。オブジェクトを別の名前付きrootName => modelObject配列内にラップする必要があるだけで、応答に不必要な深さが追加されます。これが言語のランタイムリフレクション機能に組み込まれているといいのですが。
Anurag、

4
ロギング機能でもこれが必要でした。次のことを実行できるようにしたいと思いました。log($ didTheSystemBlowUp); 次のようにログファイルに表示するには:$ didTheSystemBlowUp = 'まだ、しかしすぐに';
SeanDowney

4
また、これはvar_dump()を呼び出すときに役立ちます。そのため、複数の変数で同時に呼び出す場合、vardupmsの出力を区別するために手動でvar名を出力する必要はありません。
PHPst

回答:


37

get_defined_vars()を使用して、名前を見つけようとしている変数と同じ値を持つ変数の名前を見つけることができます。異なる変数が同じ値を持っていることが多いため、これが常に機能するとは限りませんが、これが私がこれを行うために考え得る唯一の方法です。

編集:get_defined_vars()は正しく機能していないようです。$ varが関数自体で使用されているため、「var」を返します。$ GLOBALSは機能しているようですので、それに変更しました。

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

    return false;
}

編集:明確にするために、PHPでこれを実行する良い方法はありません。これはおそらく、実行する必要がないためです。あなたがやろうとしていることを行うには、おそらくもっと良い方法があるでしょう。


2
ああ。遅いです;-)同じことを考えましたが、代わりに$ GLOBALSを使用しています。したがって、同一性比較は等しいスカラー値に対して真をもたらします($ a = 'foo'; $ b = 'foo'; assert($ a === $ b);)?
Argelbargel 2008年

実際にコードをテストしたので、関数で使用されているため、コードは常に「var」を返しました。代わりに$ GLOBALSを使用すると、何らかの理由で正しい変数名が返されます。したがって、上記のコードを$ GLOBALSを使用するように変更します。
Jeremy Ruten、

うん、気づいたがget_defined_vars()で十分だ。
ゲイリーウィロビー、

2
このコードが期待どおりに動作しないケースはたくさんあります。
troelskn 2008年

122
このコードは恐ろしく間違っています。変数がVALUEによって送信された変数と同じであることを確認することは、非常にばかげた考えです。無数の変数は、任意の時点でNULLです。無数は1に設定されています。これは狂ったようです。
Alex Weinstein、2010年

49

これを効率的に行う方法も考えられませんでしたが、これを思いつきました。以下の限られた用途で機能します。

肩をすくめる

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

関数を呼び出した行に基づいて機能し、渡された引数を見つけます。複数の引数で機能するように拡張できると思いますが、他の人が言ったように、状況をよりよく説明できれば、別の解決策はおそらくよりよく働く。


2
これは機能しますが、関数varNameが、検索する変数と同じファイルで定義されている場合のみです。
rubo77 2013年

1
ここではいくつかの以上の作品が含まれていることをよりよく実現します見つける:stackoverflow.com/a/19788805/1069083
rubo77

31

アプローチを変更し、変数名を使用することを検討しますか?

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

それならあなたはただ

print($var_name);

取得するため

FooBar

変数変数に関するPHPマニュアルへのリンクは次のとおりです


42
変数変数を広範囲に使用するシステムを使用してきました。警告させてください、それは本当に臭いが本当に速いです!
Icode4food

3
ほとんどの場合、ユーザーは変数の名前と値を取得します。"function debugvar($ varname)"と考え、彼はそれを "debugvar( 'foo')"と呼ぶつもりなので、デバッグは "foo = 123"を表示します。変数variableでは、「foo」は未定義になります。
gcb

実際に何をしているかを見てください。ちょうどあなたの例では、あなたは実際にあなたのマニュアルを読んだ$FooBar値で変数を実際に作成しますa string。これは恐ろしい私見です。変数$FooBarに値を割り当てることはありませんが、値は存在します。OUCH
Toskan、2014年

20

これがa)難しい、b)賢くないという根本的な理由について誰も言及していないようです:

  • 「変数」は、他の何かを指す単なるシンボルです。彼らは同じ値を持っているので、PHPで、それは内部的に何かにポイントがなるように(PHP実装何かが「コピー・オン・ライト」と呼ばれるどちらか、実際には同時に複数の変数のために使用することができる、「zvalを」と呼ばれる$foo = $barには必要ありません。すぐに追加のメモリを割り当てる)、または参照によって割り当てられている(または関数に渡されている)ため(例:)$foo =& $bar。したがって、zvalには名前がありません。
  • 関数にパラメーターを渡すと、(参照であっても)新しい変数が作成されます。のような匿名のものを渡すことができますが"hello"、関数内に入ると、名前を付けた変数になります。これはコード分離のかなり基本的なものです。関数が以前に呼び出さた変数に依存している場合、それはgoto適切に分離された関数というよりは似ています。
  • グローバル変数は一般に悪い考えと考えられています。ここでの例の多くは、「反映」したい変数がにあると想定しています$GLOBALSが、これは、コードの構造が適切でなく、変数のスコープが関数やオブジェクトに限定されていない場合にのみ当てはまります。
  • 変数名は、プログラマがコードを読みやすくするためにあります。目的に合わせて変数の名前を変更することは、非常に一般的なリファクタリングの慣行であり、全体の要点は、それが違いをもたらさないということです。

今、私はこれがデバッグのために必要であることを理解しています(ただし、提案された使用法のいくつかはそれをはるかに超えています)が、一般化されたソリューションとしては、実際にはそれほど考えられないかもしれません。デバッグ関数で変数が "$ file"と呼ばれている場合"、それはまだコード内の何十もの" $ file "変数のいずれか、または" $ filename "を呼び出したが、" $ file "と呼ばれるパラメーターを持つ関数に渡されている変数である可能性があります。

はるかに有用な情報は、コード内でデバッグ関数が呼び出された場所です。エディターでこれをすばやく見つけることができるため、自分で出力していた変数を確認でき、式全体を一度に変数に渡すこともできます(例:)debug('$foo + $bar = ' . ($foo + $bar))

そのため、デバッグ関数の上部でこのスニペットを使用できます。

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

すでにいくつかの良い答えがあります。だから、これは現実に直面しても悲観的だ。
a20 2017年

@ a20すべての回答には、いつ使用できるか、いつ使用できるかについて大きな注意が必要です。実際には不可能であるため、変数からその名前への単純なルックアップはありません。一部はデバッグ目的で多くのファンキーなリフレクションを行いますが、これは問題ありません。ただし、私の意見では、行番号を出力してソースの行を自分で検索するか、またはXDebugのようなインタラクティブなデバッガーを使用する方がよいとしています。
IMSoP 2017年

14

これはまさにあなたが望むものです-それは与えられた変数の名前をエコーするすぐに使える「コピーとドロップイン」機能です:

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

使用法:print_var_name($ FooBar)

印刷:FooBar

ヒント これで、関数の名前を変更できます。関数は引き続き機能し、関数を1行で数回使用することもできます。@Cliffordlifeに感謝


3
クール、これをありがとう。$ pat行を$pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';このように少し変更して、このデバッグ関数が何と呼ばれるかは気にせず、関数に渡されるもの、つまり$ helloまたは "hello"を正確に取得します(渡された変数の$一致を削除しました同じ行で)
Cliffordlife

1
素晴らしいコード!ありがとう!ただし、すべてのインスタンスで機能するとは限りません。私のubuntu 18.04とphp 7.2.19でのテスト結果:同じコード行で複数回使用すると、1つまたは別の式で使用されているかどうかに関係なく機能しません。ライン。同じ式で使用されているが別の行で使用されている場合は機能します。動作するさまざまな行のさまざまな式で使用されます。
Matty

1
また、その関数は「var_dump」なしの1行にある必要がありprint_var_name, echo, var_dumpます$variable); echo ' '; var_dump($variable
BG Bruno

13

PHP.netのLucasは、変数が存在するかどうかを確認する信頼できる方法を提供しました。彼の例では、変数のグローバル変数配列(またはスコープ配列)のコピーを反復処理し、値をランダムに生成された値に変更し、コピーされた配列で生成された値を確認します。

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

次に試してください:

$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で彼の投稿を必ず確認してください:http ://php.net/manual/en/language.variables.php


現在のスコープを配列形式でどのように取得しますか?
セバスティアンGrignoli

いいね!私にとって欠けているのはbreak;、foreach +で等しいことがわかったときだけです。関数内で定義されている場合でも、var_nameを自動的に取得するための使用可能な基本構造を作成しました。コピー&ペーストを頻繁に行っている場合、またはそれを改善するためのより良いアイデアがある場合は、variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2

これはおそらく、ジョブを実行する最も高速でクリーンな方法です。デバッグにはパフォーマンスの問題が含まれている可能性があります。この関数は、中断することなく割り当てるだけでなく、foreachループで直接返す必要があります。GLOBALSが大きくなると、パフォーマンスが大幅に向上する可能性があります。
John

13

デバッグのために検査機能を作りました。これはステロイドのprint_r()に似ていますが、Krumoによく似ていますが、オブジェクトに対しては少し効果的です。私はvar名の検出を追加したかったので、このページへのNick Prestaの投稿に触発されてこれを思いつきました。変数名だけでなく、引数として渡された式を検出します。

これは、渡された式を検出するラッパー関数のみです。ほとんどの場合で機能します。同じコード行で関数を複数回呼び出す場合は機能しません。

これは正常に動作します:die(inspect($ this-> getUser()-> hasCredential( "delete"));

inspect()は、渡された式を検出する関数です。

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

}

以下は、実行中のインスペクター関数(および私のdInspectクラス)の例です。

http://inspect.ip1.cc

そのページのテキストはスペイン語ですが、コードは簡潔で本当に理解しやすいです。


1
エラー、NuSphareデバッガーがインストールされていることに依存していませんか?
Mawg氏はモニカを

そこで、このコードの簡略版を投稿しました。また、この回答を変更しました。これで、すべてのPHP5実装で実行できるようになります。
セバスティアンGrignoli

このような独創性が、私が人々が「できない」または「不可能」と言うのを見るたびに笑う理由です。この場合、ラスムス自身も含まれます。Sebastiánおよびこの回答に貢献した可能性のある他の人への称賛。
夜型フクロウ

1
Night Owlに感謝しますが、これは完全な証拠ではないと主張します(回答のとおり、「inspect()」関数が1行で2回以上呼び出されると失敗します!)。これをプロダクションで使用することはありません。これは、本番サーバーに到達してはならないデバッグインスペクタ機能専用です。
セバスティアンGrignoli

7

php.netから

@Alexandre-短い解決策

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

@Lucas-使用法

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

多くの回答がこれの有用性を疑問視しています。ただし、変数の参照を取得すると非常に便利です。特にオブジェクトと$ thisの場合。私のソリューションはオブジェクトで動作し、プロパティ定義オブジェクトとしても動作します:

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

上記の例:

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

上記の回答から多くの変数に適応し、優れたパフォーマンスで、1つの$ GLOBALSスキャンで多くの

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

変数が交換可能な場合、使用する変数を決定するロジックがどこかに必要です。あなたがする必要があるすべてはあなたが$variable他のすべてをしている間そのロジック内に変数名を置くことです。

私たちは皆、あなたがこれを何のために必要としているのかを理解するのに苦労していると思います。サンプルコードまたはあなたが実際にしようとしているものの説明を行うかもしれないのヘルプを、私はあなたにしている道を疑う、これをoverthinking。


1

私は実際にこれの有効なユースケースを持っています。

私は関数cacheVariable($ var)を持っています(わかりました、関数cache($ key、$ value)を持っていますが、前述のように関数が欲しいです)。

目的は次のとおりです。

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

...

// another session

...

$myColour = getCachedVariable('colour');

私は試しました

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
}

私も試しました

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

しかし、これも失敗します... :(

確かに、私はcache( 'colour'、$ colour)を続けることができますが、私は怠惰です、あなたは知っています...;)

したがって、関数に渡されたときに、変数の元の名前を取得する関数が必要です。関数内では、どうやらそれを知る方法はありません。上記の2番目の例で参照によりget_defined_vars()を渡すことは、私にいくらか役立ちました(そのアイデアについてJean-Jacques Gueganに感謝します)。後者の関数は機能し始めましたが、ローカル変数( '変数'ではなく '色')を返すだけでした。

get_func_args()とget_func_arg()、$ {}-constructs、key()を組み合わせて使用​​することはまだ試みていませんが、同様に失敗すると思います。


1
非常に基本的な問題は、変数ではなく関数にを渡すことです。変数は一時的なものであり、そのスコープに固有です。多くの場合、変数名は値をキャッシュしたいキーではない可能性があり、多くの場合、(例のように)異なる名前の変数に復元します。キーの名前を繰り返して変数を覚えておくことが本当に面倒な場合は、を使用してください。cacheVariable(compact('color'))
deceze

1

私はこれを持っています:

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

私はこれを好みます:

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

既存の関数は、赤い枠の付いた黄色のボックスを表示し、各変数を名前と値で示します。配列ソリューションは機能しますが、必要なときにタイプするのは少し複雑です。

それは私のユースケースであり、はい、デバッグに関係しています。私はそれ以外の場合の使用に疑問を抱く人々に同意します。


1

これはに基づいて私の解決策です Jeremy Ruten

class DebugHelper {

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

それを使う

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

0

単純な関数を作成して教えてみませんか?

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

私はこれを探していましたが、名前を渡すことにしただけです。通常、名前はクリップボードにあります。

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

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

0

これを実現するには、compact()を使用できます。

$FooBar = "a string";

$newArray = compact('FooBar');

これにより、変数名をキーとする連想配列が作成されます。その後、必要な場所でキー名を使用して配列をループできます。

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

2
かっこいいですが、使用するには変数の名前を知っている必要があります。OPはプログラムで変数名を決定しようとしています。
コーダー

0

変数名とその値を知りたいと思います。これを行うには、連想配列を使用できます。

配列キーには変数名を使用します。

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

変数名を取得するには、を使用しますarray_keys($vars)。これは、配列で$varsキーとして使用されている変数名の配列を返します。


変数を宣言する通常の方法よりもはるかに遅い。
デビッドスペクター

0

これは古く、すでに回答済みですが、実際に探していました。私はこの回答を投稿して、回答の一部を改善する時間を少し節約できるようにしています。

オプション1:

$data = array('$FooBar');  

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

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

プリント:

FooBar

どんな理由であれ、あなたはこのような状況にいることに気づくでしょう、それは実際に機能します。


オプション2:

$FooBar = "a string";  

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

場合は$FooBar一意の値を保持し、それはFooBarの"を出力します。$FooBar空またはnullの場合、最初に見つかった空またはnull文字列の名前を出力します。

次のように使用できます。

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

0

これは私がやった方法です

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

使用法

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

注:一部のPHP 7バージョンは、のバグのために正しく動作しませんarray_search$GLOBALS、他のすべてのバージョンは動作します。

これを参照してくださいhttps://3v4l.org/UMW7V


-1

これを使用して、ユーザー変数をグローバルから切り離し、現時点で変数をチェックします。

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その出力から判断すると、print implode( ' ', array_keys( $GLOBALS ));「デフォルト」グローバルの数に関する誤った仮定のように見えます。私のシステムには7つのスーパーグローバルがあります:$ _GET、$ _ POST、$ _ COOKIE、$ _ FILES、$ _ ENV、$ _ REQUEST、$ _ SERVER。また、argvとargcもあります。したがって、オフセットは9である必要があります。デフォルトではとにかく配列の最後まで実行するだけなので、3番目のパラメーター(長さ)を指定しても意味がありません。
ジェフ

-2

素早いと思われるかもしれませんが、私の個人的な好みは、次のような関数/メソッドを使用することです。

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

基本的には、名前が必要な変数をキーとして使用して、1つのnull /空の要素を含む連想配列を作成するだけです。

次に、array_keysを使用してそのキーの値を取得し、それを返します。

これは明らかに乱雑になり、実稼働環境では望ましくありませんが、提示された問題に対しては機能します。


1
つまり、変数の名前ではなく、変数の値です。他の場所で指摘されているように、名前は関数の境界を越えて移植できません。
オーウェンベレスフォード2014年

3
この関数は文字通りトリム($ var)を返すだけなので、マイナス1です。
Alexar 2015

-3

変数名を取得するためにグローバルを使用する必要がある理由...以下のように使用できます。

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

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

6
OPが変数名を知らないためです。もしそうなら、彼はgetVarName()機能を必要としません。;-)
FtDRbwLXw6 2013

1
は変数ではなく文字列であるため、これ'$variableName'は変数の名前を文字列として返しません。あなたがでこのトリックを行うことができる場合getVarName($variableName);、あなたは賛成票を獲得します:)
ダニエルW.

-4

ユースケースが本当にわかりません... print_var_name($ foobar)と入力する場合、代わりにprint( "foobar")と入力するのが難しい(そして違う)のは何ですか?

これを関数で使用したとしても、変数のローカル名を取得するためです...

いずれにせよ、必要なものがあった場合のリフレクションマニュアルです。


Print( "foobar")は他の変数を処理しません。
ゲイリーウィロビー

7
使用例:同じ値のダンプを返すコードにデバッグポイントがほとんどありません。最初に実行されたものをどのようにして知っていますか?ラベルを印刷することは非常に便利です。
takeshin

次に、十分なプログラミングを行っていません。私が出会ったほとんどの言語には、これを行う方法があり、通常は簡単です。
b01

@ b01たくさんやりました。これを可能にする多くの言語があることを私は完全に認識していますが、それだけではあまり意味がありません。多くの言語ではgotoを簡単に実行する方法がいくつか提供されているため、適切なフロー制御を記述しないように使用する必要があるわけではありません。これは私の見解では同様のケースです。正当なケースがあることは間違いありません。それが、適切なユースケースについて疑問に思っていた理由です。
Vinko Vrsalovic 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.