PHP에서 변수 이름을 문자열로 가져오려면 어떻게 해야 합니까?
예를 들어 다음과 같은 PHP 코드가 있습니다.
$FooBar = "a string";
그러면 다음과 같은 기능이 필요합니다.
print_var_name($FooBar);
인쇄:
FooBar
어떻게 하면 좋을까요?이게 PHP에서도 가능합니까?
나도 이걸 효율적으로 할 수 있는 방법이 생각나지 않았지만 이걸 생각해냈어.아래 제한된 용도로 사용할 수 있습니다.
어깨를 으쓱하다
<?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
)
이 기능은 함수를 호출한 행을 기반으로 작동하며, 여기서 전달한 인수를 찾습니다.여러 주장으로 확대될 수 있다고 생각합니다만, 다른 사람들이 말한 것처럼 상황을 더 잘 설명할 수 있다면 다른 해결책이 더 효과적일 것입니다.
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에서는 이것을 실행하는 좋은 방법이 없습니다.이것은 아마 당신이 그것을 할 필요가 없기 때문일 것입니다.당신이 하려는 일을 더 잘 할 수 있는 방법이 있을 거예요.
접근 방식을 변경하고 변수 이름을 사용하는 것을 고려할 수 있습니다.
$var_name = "FooBar";
$$var_name = "a string";
그러면 그냥
print($var_name);
갖기 위해
FooBar
변수 관련 PHP 설명서에 대한 링크입니다.
a) 이것이 어렵고 b) 현명하지 못한 근본적인 이유를 아무도 언급하지 않은 것으로 보인다.
- "변수"는 다른 것을 가리키는 기호일 뿐입니다.PHP에서는으로 "에 실제로에 사용할 수 (PHP는 "라고 불리는 실장하고 때문에 PHP는 "zval"이라고 불리는 것을 PHP가 구현하고 ).
$foo = $bar
바로 참조에 있기 메모리 할당은 메모리를 할당할 필요가 없습니다.또는 참조에 의해 할당(또는 기능에 전달)되어 있기 때문입니다(예:$foo =& $bar
zval 는 z z z z z z z z z z - 매개변수를 함수에 전달하면 새 변수가 생성됩니다(참조 변수인 경우에도).뭔가 익명으로 넘길 수도 있어
"hello"
일단 함수에 들어가면 어떤 변수라고 부르든 상관없습니다.이것은 코드 분리에 매우 기초적입니다. 함수가 호출되는 변수에 의존할 경우, 이는 코드 분리에 더 가깝습니다.goto
제대로 분리된 기능보다 더 낫습니다. - 글로벌 변수는 일반적으로 좋지 않은 아이디어로 간주됩니다.에서는 '가 '반성하다', '반성하다', '반성하다', '반성하다'에 하는 경우가 .
$GLOBALS
단, 이것은 코드를 잘못 구성해서 변수가 함수나 객체에 스코핑되지 않은 경우에만 해당됩니다. - 프로그래머가 코드를 읽을 수 있도록 변수 이름이 있습니다.목적에 맞게 변수 이름을 변경하는 것은 매우 일반적인 리팩터링 방식이며, 요점은 차이가 없다는 것입니다.
디버깅을 위해 이것이 필요한 것은 이해하지만(일부 제안된 사용방법이 이를 훨씬 능가하지만) 일반적인 솔루션으로서 실제로는 생각만큼 도움이 되지 않습니다.디버깅 함수에 의해 변수가 "$file"이라고 표시되어도 코드 내의 수십 개의 "$file" 변수 중 하나일 수 있습니다.ve는 "$file"을 호출했지만 파라미터가 "$file"인 함수에 전달되고 있습니다.
훨씬 더 유용한 정보는 코드 내의 디버깅 함수가 호출된 위치입니다.편집기에서 이를 빠르게 찾을 수 있기 때문에 출력한 변수를 직접 확인할 수 있으며 전체 식을 한 번에 전달할 수도 있습니다(예:debug('$foo + $bar = ' . ($foo + $bar))
를 참조해 주세요.
이를 위해 디버깅 기능의 맨 위에 다음 스니펫을 사용할 수 있습니다.
$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];
원하는 것은 바로 다음과 같습니다.지정된 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 '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>';
}
사용방법: print_var_name($FooBar)
인쇄: FooBar
★★★
이제 기능 이름을 변경할 수 있으며, 이 기능은 계속 작동하며 한 줄로 여러 번 사용할 수 있습니다!@@Cliffordlife 분분 @ @ @ 덕 @ 덕 @ 。
!!고!!!!!@@Blue-Water ★★님 입니다.
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
디버깅을 위해 검사 기능을 만들었습니다.스테로이드제의 print_r()와 같은 것으로, Krumo와 비슷하지만, 물건에 대해서는 조금 더 효과적입니다.저는 Var name detection을 추가하고 싶었고 Nick Presta가 이 페이지에 올린 글에서 영감을 얻어 이것을 만들었습니다.변수 이름뿐만 아니라 인수로 전달된 모든 식을 탐지합니다.
전달된 식을 검출하는 래퍼 함수만 해당됩니다.대부분의 경우에 효과가 있습니다.같은 줄의 코드로 함수를 여러 번 호출하면 작동하지 않습니다.
이것은 정상적으로 동작합니다.die ( inspect ( $ this - > get User ( ) - > has Credential ( " 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);
}
다음은 인스펙터 함수(및 my dInspect 클래스)의 동작 예를 나타냅니다.
그 페이지에는 스페인어로 된 텍스트가 있습니다만, 코드는 간결하고 알기 쉽습니다.
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
?>
많은 답변이 이것의 유용성에 의문을 제기합니다.그러나 변수에 대한 참조를 얻는 것은 매우 유용할 수 있습니다.특히 물건이나 $이 있는 경우에는 더욱 그렇습니다.내 솔루션은 객체 및 속성 정의 개체와 함께 작동합니다.
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
많은 변수에 대해 위의 답변에서 수정되었으며 성능이 우수하며 많은 변수에 대해 단 한 번의 $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
)
)
이를 위해 compact()를 사용할 수 있습니다.
$FooBar = "a string";
$newArray = compact('FooBar');
그러면 변수 이름을 키로 하는 연관 배열이 생성됩니다.그런 다음 필요한 키 이름을 사용하여 어레이를 루프할 수 있습니다.
foreach($newarray as $key => $value) {
echo $key;
}
변수를 상호 변경할 수 있는 경우 사용할 변수를 결정하는 논리가 어딘가에 있어야 합니다.변수 이름만 입력하면 됩니다.$variable
그 논리 안에서 다른 모든 것을 하는 동안에도 말이죠.
우리 모두 당신이 왜 이걸 필요로 하는지 이해하는데 어려움을 겪고 있는 것 같아요.샘플 코드나 실제로 하려고 하는 일에 대한 설명이 도움이 될 수도 있지만, 너무 지나친 생각인 것 같아요.
실제로 유효한 사용 사례가 있습니다.
함수 cacheVariable($var)을 가지고 있습니다(예, 함수 캐시($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));
}
하지만 이것 또한 실패한다...:(
물론 캐시('colour', $colour)는 계속 할 수 있지만, 저는 게을러요.;)
그래서 제가 원하는 것은 변수가 함수에 전달되었을 때 원래 이름을 얻는 함수입니다.기능 내에서는 그것을 알 수 있는 방법이 없는 것 같습니다.위의 두 번째 예에서 get_defined_vars()를 참조로 전달하면 (Jean-Jacques Guegan 덕분에) 어느 정도 도움이 되었습니다.후자 함수는 작동을 시작했지만 여전히 로컬 변수('색상'이 아닌 변수')만 반환했습니다.
get_func_args()와 get_func_arg(), ${}-constructs 및 key()를 조합하여 사용해 본 적은 없지만, 이것도 실패할 것으로 예상됩니다.
이거 있어요.
debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));
나는 이것을 선호한다:
debug_echo($query, $nrUsers, $hdr);
기존 함수는 빨간색 아웃라인과 함께 노란색 상자를 표시하고 각 변수를 이름과 값으로 표시합니다.어레이 솔루션은 동작하지만 필요할 때 입력하기에는 조금 복잡합니다.
이것이 저의 사용 사례이며, 디버깅과 관련이 있습니다.나는 달리 그것의 사용에 의문을 제기하는 사람들의 의견에 동의한다.
이하를 기반으로 한 솔루션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')
);
변수 이름과 값을 알고 싶어할 것 같아요.이를 위해 연관 배열을 사용할 수 있습니다.
배열 키에 변수 이름 사용:
$vars = array('FooBar' => 'a string');
변수 이름을 가져오려면array_keys($vars)
에 사용된 변수 이름의 배열을 반환합니다.$vars
키와 같이 배열합니다.
나는 이렇게 했다.
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 를 참조해 주세요.
변수 이름을 출력할 수 있는 사전 정의된 함수는 PHP에 없습니다.이렇게 하다, 하다, 하다, 하다, 하다, 하다의 할 수 있습니다.get_defined_vars()
이름 및 값을 포함하여 스코프에 정의된 모든 변수를 반환합니다.하다
<?php
// Function for determining the name of a variable
function getVarName(&$var, $definedVars=null) {
$definedVars = (!is_array($definedVars) ? $GLOBALS : $definedVars);
$val = $var;
$rand = 1;
while (in_array($rand, $definedVars, true)) {
$rand = md5(mt_rand(10000, 1000000));
}
$var = $rand;
foreach ($definedVars as $dvName=>$dvVal) {
if ($dvVal === $rand) {
$var = $val;
return $dvName;
}
}
return null;
}
// the name of $a is to be determined.
$a = 1;
// Determine the name of $a
echo getVarName($a);
?>
자세한 내용은 변수 이름을 PHP에서 문자열로 가져오는 방법을 참조하십시오.
그냥 간단한 기능을 만들어서 말하지 그래요?
/**
* 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' );
찾고 있었는데, 이름을 전달하기로 했어요. 어차피 클립보드에 이름이 있어요.
function VarTest($my_var,$my_var_name){
echo '$'.$my_var_name.': '.$my_var.'<br />';
}
$fruit='apple';
VarTest($fruit,'fruit');
이게 오래되고 이미 대답한 거 알지만 사실 이걸 찾고 있었어요.저는 사람들이 답을 다듬는 시간을 절약하기 위해 이 답변을 올립니다.
옵션 1:
$data = array('$FooBar');
$vars = [];
$vars = preg_replace('/^\\$/', '', $data);
$varname = key(compact($vars));
echo $varname;
인쇄:
푸바
어떤 이유로든 이런 상황에 처하게 되겠지만, 실제로 효과가 있습니다.
.
2: § 2:
$FooBar = "a string";
$varname = trim(array_search($FooBar, $GLOBALS), " \t.");
echo $varname;
if$FooBar
'FooBar'를 사용합니다. if$FooBar
이므로 처음 빈 늘됩니다.empty "null "은 null "로 출력됩니다.
다음과 같이 사용할 수 있습니다.
if (isset($FooBar) && !is_null($FooBar) && !empty($FooBar)) {
$FooBar = "a string";
$varname = trim(array_search($FooBar, $GLOBALS), " \t.");
}
기타 용도:
어깨를 으쓱하다
function varsToArrayAssoc(...$arguments){
$bt = debug_backtrace();
$file = file($bt[0]['file']);
$src = $file[$bt[0]['line']-1];
$pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
$vars =explode(',',substr_replace(trim(preg_replace($pat, '$2', $src)) ,"", -1));
$result=[];
foreach(func_get_args() as $key=>$v){
$index=trim(explode('$',$vars[$key])[1]);
$result[$index]=$v;
}
return $result;
}
$a=12;
$b=13;
$c=123;
$d='aa';
var_dump(varsToArrayAssoc($a,$b,$c,$d));
이를 통해 현재 체크할 변수에서 사용자 변수를 글로벌에서 분리합니다.
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 ;
}
}
빠르고 지저분하다고 생각될 수 있지만 개인적으로는 다음과 같은 기능/방법을 사용하는 것이 좋습니다.
public function getVarName($var) {
$tmp = array($var => '');
$keys = array_keys($tmp);
return trim($keys[0]);
}
기본적으로 하나의 null/빈 요소를 포함하는 연관 배열만 생성하며, 이름을 원하는 변수를 키로 사용합니다.
그런 다음 array_keys를 사용하여 해당 키의 값을 가져와 반환합니다.
이것은 분명히 금방 혼란스러워지기 때문에 실제 가동 환경에서는 바람직하지 않지만, 제시된 문제에는 효과가 있습니다.
왜 우리가 변수 이름을 얻기 위해 지구본을 사용해야 하는지...아래와 같이 간단하게 사용할 수 있습니다.
$variableName = "ajaxmint";
echo getVarName('$variableName');
function getVarName($name) {
return str_replace('$','',$name);
}
사용 사례를 정말 못 봤어요...print_var_name($foobar)을 입력하는 경우 print("foobar")를 입력하는 것이 어려운(및 다른) 점은 무엇입니까?
함수에서 이것을 사용하더라도 변수의 로컬 이름을 얻을 수 있기 때문입니다.
어쨌든, 여기 당신이 필요한 것이 있을 때를 대비해서 성찰 매뉴얼이 있습니다.
언급URL : https://stackoverflow.com/questions/255312/how-to-get-a-variable-name-as-a-string-in-php
'itsource' 카테고리의 다른 글
JSTL과 함께 EL을 사용하여 Enum 값에 액세스합니다. (0) | 2022.09.30 |
---|---|
VueJS 라우터 - 서브루트와 Vuetify를 사용할 때 여러 활성화루트를 정지하려면 어떻게 해야 하나요? (0) | 2022.09.30 |
galera 클러스터에서 노드를 삭제하려면 어떻게 해야 합니까? (0) | 2022.09.29 |
Windows에 Maven을 설치할 수 없습니다: "JAVA_"HOME이 비활성 디렉토리로 설정되었습니다." (0) | 2022.09.29 |
도커 컨테이너를 어떻게 유지합니까? (0) | 2022.09.29 |