PHP에서 변수 이름을 문자열로 얻는 방법은 무엇입니까?
이 PHP 코드가 있다고 가정 해보십시오.
$FooBar = "a string";
그런 다음 다음과 같은 기능이 필요합니다.
print_var_name($FooBar);
어떤 인쇄 :
FooBar
이것을 달성하는 방법에 대한 아이디어가 있습니까? PHP에서도 가능합니까?
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 에서이 작업을 수행하는 좋은 방법이 없습니다. 아마도 그렇게 할 필요가 없기 때문일 것입니다. 당신이하려는 일을하는 더 좋은 방법이있을 것입니다.
나는 이것을 효율적으로 수행하는 방법을 생각할 수 없었지만 이것을 생각해 냈습니다. 아래의 제한된 용도로 작동합니다.
어깨를 으쓱하다
<?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
)
함수를 호출 한 줄을 기반으로 작동합니다. 여기서 전달 된 인수를 찾습니다. 여러 인수와 함께 작동하도록 확장 할 수 있다고 생각하지만 다른 사람들이 말했듯이 상황을 더 잘 설명 할 수 있다면 다른 해결책이 될 것입니다 더 잘 작동합니다.
접근 방식을 변경하고 변수 변수 이름을 사용하는 것을 고려할 수 있습니까?
$var_name = "FooBar";
$$var_name = "a string";
그럼 그냥
print($var_name);
얻을
FooBar
변수 변수에 대한 PHP 매뉴얼 링크는 다음과 같습니다.
아무도 근본적인 이유를 언급 한 것 같다 왜 이) 현명) 하드와 B A입니다 :
- "변수"는 다른 것을 가리키는 기호 일뿐입니다. PHP에서는 내부적으로 뭔가 포인트가 같은 값을 가지고 있기 때문에 중 (PHP 구현 뭔가라는 사실은 동시에 여러 변수에 사용할 수있는,는 "zval을"소위 "복사 (copy-on-write)"가이 있도록
$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'];
디버깅 이유로 검사 기능을 만들었습니다. 스테로이드의 print_r ()과 비슷하지만 Krumo와 비슷하지만 객체에는 조금 더 효과적입니다. var 이름 감지를 추가하고 싶었습니다.이 페이지의 Nick Presta의 게시물에서 영감을 얻었습니다. 변수 이름뿐만 아니라 인수로 전달 된 표현식을 감지합니다.
전달 된 표현식을 감지하는 랩퍼 함수입니다. 대부분의 경우에 작동합니다. 동일한 코드 줄에서 함수를 두 번 이상 호출하면 작동하지 않습니다.
이것은 잘 작동합니다 : die ( inspect ($ this-> getUser ()-> hasCredential ( "삭제")) );
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 클래스)의 예는 다음과 같습니다.
해당 페이지에는 텍스트가 스페인어로되어 있지만 코드는 간결하고 이해하기 쉽습니다.
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
이것은 정확히 당신이 원하는 것입니다-주어진 var의 이름을 반영하는 "복사 및 드롭 인"기능을 사용할 준비가되었습니다.
function print_var_name(){
// read backtrace
$bt = debug_backtrace();
// read file
$file = file($bt[0]['file']);
// select exact print_var_name($varname) line
$src = $file[$bt[0]['line']-1];
// search pattern
$pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
// extract $varname from match no 2
$var = preg_replace($pat, '$2', $src);
// print to browser
echo trim($var);
}
사용법 : print_var_name ($ FooBar)
인쇄 : FooBar
힌트 이제 기능의 이름을 바꿀 수 있으며 여전히 작동하며 한 줄에 여러 번 기능을 사용할 수 있습니다! @Cliffordlife 감사합니다
에서 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;
}
?>
@ 루카스-사용법
<?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
?>
많은 응답자들이 이것의 유용성에 의문을 제기합니다. 그러나 변수에 대한 참조를 얻는 것이 매우 유용 할 수 있습니다. 특히 객체와 $ 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
좋은 성능과 많은 변수에 대한 위의 답변에서 적응하여 많은 $ 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
)
)
변수를 교환 할 수 있는 경우 사용할 변수를 결정하는 어딘가에 논리가 있어야합니다 . $variable
다른 모든 일을하는 동안 변수 이름을 해당 논리 내에 넣으면 됩니다.
나는 우리가 당신이 무엇을 필요로하는지 이해하는데 어려움을 겪고 있다고 생각합니다. 샘플 코드 또는 당신이 실제로하려고하는지에 대한 설명을 할 힘 도움말을,하지만 난 당신에게있는 거 방법을 의심, 방법 이 지나친.
실제로 유효한 사용 사례가 있습니다.
cacheVariable ($ var) 함수가 있습니다 (ok, 함수 캐시 ($ 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에게 감사드립니다) 다소 도움이되었습니다. 후자의 함수가 작동하기 시작했지만 여전히 로컬 변수 ( 'color'가 아닌 'variable') 만 반환했습니다.
get_func_args () 및 get_func_arg (), $ {}-constructs 및 key ()를 아직 사용하지 않았지만 실패 할 것으로 예상됩니다.
내가 이거 가지고있어:
debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));
나는 이것을 선호한다 :
debug_echo($query, $nrUsers, $hdr);
기존 함수는 빨간색 윤곽선이있는 노란색 상자를 표시하고 각 변수를 이름과 값으로 표시합니다. 배열 솔루션은 작동하지만 필요할 때 타이핑하기에는 약간 복잡합니다.
그것은 내 유스 케이스이며 예, 디버깅과 관련이 있습니다. 나는 그렇지 않으면 그 사용에 의문을 가진 사람들에 동의합니다.
간단한 함수를 만들어서 말해 보지 않겠습니까?
/**
* 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' );
여기에 내 솔루션이 있습니다. 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')
);
나는 이것을 찾고 있었지만 그냥 이름을 전달하기로 결정했습니다. 어쨌든 보통 클립 보드에 이름이 있습니다.
function VarTest($my_var,$my_var_name){
echo '$'.$my_var_name.': '.$my_var.'<br />';
}
$fruit='apple';
VarTest($fruit,'fruit');
이것을 달성하기 위해 compact ()를 사용할 수 있습니다.
$FooBar = "a string";
$newArray = compact('FooBar');
변수 이름을 키로 사용하여 연관 배열을 만듭니다. 그런 다음 필요한 키 이름을 사용하여 배열을 반복 할 수 있습니다.
foreach($newarray as $key => $value) {
echo $key;
}
변수 이름을 값으로 알고 싶다고 생각합니다. 이를 위해 연관 배열을 사용할 수 있습니다.
배열 키에 변수 이름을 사용하십시오.
$vars = array('FooBar' => 'a string');
변수 이름을 얻으려면을 사용 array_keys($vars)
하면 배열 $vars
에서 키로 사용 된 변수 이름의 배열을 반환 합니다.
이것을 사용하여 사용자 변수를 전역에서 분리하여 현재 변수를 확인하십시오.
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
'Programming' 카테고리의 다른 글
Wildfly의 Spring Security : 필터 체인 실행 중 오류 (0) | 2020.05.12 |
---|---|
C # 5 비동기 CTP : EndAwait 호출 전에 생성 된 코드에서 내부 "상태"가 0으로 설정된 이유는 무엇입니까? (0) | 2020.05.12 |
Flux 앱에서 Ajax 요청은 어디에서해야합니까? (0) | 2020.05.12 |
모바일 장치에서 전화 번호로 전화하기 위해 하이퍼 링크를 만드는 방법은 무엇입니까? (0) | 2020.05.12 |
저자의 모든 지점에서 한 번에 로그를 기록하는 방법은 무엇입니까? (0) | 2020.05.12 |