PHP में एक स्ट्रिंग के रूप में एक चर नाम कैसे प्राप्त करें?


201

कहो कि मेरे पास यह PHP कोड है:

$FooBar = "a string";

मुझे तब इस तरह के एक समारोह की आवश्यकता है:

print_var_name($FooBar);

जो प्रिंट करता है:

FooBar

किसी भी विचार यह कैसे प्राप्त करने के लिए? क्या यह PHP में भी संभव है?


9
अगर आपको डिबगिंग के लिए कुछ भी चाहिए, तो आप कुछ गलत कर रहे हैं। आपका उपयोग-मामला क्या है?
ट्रॉयल्सनोक

10
अच्छा प्रश्न। मुझे डिबगिंग के लिए समान की आवश्यकता थी।
ताकेशिन

17
+1 - मुझे एक मॉडल PHP ऑब्जेक्ट से ऑटो-जेनरेटिंग XML या JSON प्रतिक्रिया के लिए इसकी आवश्यकता थी। ऑब्जेक्ट को किसी अन्य नामित rootName => modelObjectसरणी के अंदर लपेटने से प्रतिक्रिया में अनावश्यक गहराई जुड़ जाती है। काश यह भाषा की रनटाइम रिफ्लेक्शन क्षमताओं में बेक किया जाता।
अनुराग

4
मुझे एक लॉगिंग फ़ंक्शन में भी इसकी आवश्यकता थी। मैं निम्नलिखित करने में सक्षम होना चाहता था: लॉग ($ didTheSystemBlowUp); लॉग फ़ाइल में दिखाई देने के लिए जैसे: $ didTheSystemBlowUp = 'अभी तक नहीं, लेकिन बहुत जल्द';
सीनडाउन

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
आह। धीमा करने के लिए किया ;-) एक ही सोचा, लेकिन इसके बजाय $ $ का उपयोग कर। तो पहचान की तुलना स्केलर मूल्यों ($ a = 'foo'; $ b = 'foo' के बराबर होती है)? ($ A = $ b)?)
अरगेलबर्गल

दरअसल अब जब मैंने अपने कोड का परीक्षण कर लिया है, तो मेरा कोड हमेशा 'var' लौटाता है क्योंकि इसका उपयोग फ़ंक्शन में किया जा रहा है। जब मैं इसके बजाय $ GLOBALS का उपयोग करता हूं, तो यह किसी कारण से सही चर नाम देता है। तो मैं $ GLOBALS का उपयोग करने के लिए उपरोक्त कोड बदल दूंगा।
जेरेमी रुटेन

हाँ, मुझे एहसास हुआ लेकिन get_defined_vars () पर्याप्त टा था।
गैरी विल्बोबी

2
ऐसे बहुत से मामले हैं जहाँ यह कोड अपेक्षा के अनुरूप व्यवहार नहीं करेगा।
ट्रोल्सनॉक

122
यह कोड बुरी तरह से गलत है। चर को देखने के लिए जाँच करना वैसा ही है जैसा कि VALUE द्वारा भेजा गया एक बहुत ही गूंगा विचार है। चर के असंख्य किसी भी बिंदु पर पूर्ण होते हैं। Myriads 1 करने के लिए सेट कर रहे हैं। यह सिर्फ पागल है।
एलेक्स वेनस्टेन

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 को उसी फ़ाइल में परिभाषित किया गया है जिस तरह से चर पाया जा सकता है।
रूबो77

1
यहाँ आप एक बेहतर कार्यान्वयन पाते हैं जो कई पर काम करता है: इसमें शामिल हैं: stackoverflow.com/a/19788805/1069083
rubo77

31

आप अपने दृष्टिकोण को बदलने और एक परिवर्तनशील चर नाम का उपयोग करने पर विचार कर सकते हैं?

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

तो आप बस कर सकते हैं

print($var_name);

लेना

FooBar

यहाँ वैरिएबल चर पर PHP मैनुअल का लिंक दिया गया है


42
मैंने एक ऐसी प्रणाली के साथ काम किया है जो बड़े पैमाने पर परिवर्तनीय चर का उपयोग करती है। मुझे आपको चेतावनी दी है, यह वास्तव में तेजी से बदबूदार हो जाता है!
Icode4food

3
अधिकांश मामलों में उपयोगकर्ता एक var का नाम और मान प्राप्त करना चाहते हैं। "डिबगवर ($ varname)" पर विचार करें और वह इसे "डिबगवार ('फू') कहने का इरादा रखता है, इसलिए डीबग" फू = 123 "दिखाएगा। परिवर्तनशील चर के साथ उन्हें 'फू' प्राप्त नहीं होगी।
जीसीबी

बस देखो कि तुम वास्तव में क्या कर रहे हो। वहीं आपके उदाहरण में आप वास्तव में एक वैरिएबल बनाते हैं $FooBarजिसका मूल्य a stringसिर्फ आपके मैनुअल को पढ़ता है। यह भयानक इम्हो है। आप चर को कभी भी $FooBarमान नहीं देते हैं , लेकिन यह वहाँ है। ओह
Toskan

20

कोई मौलिक कारणों का उल्लेख किया है लगता है क्यों यह एक है) हार्ड और ख) मूर्ख:

  • एक "वैरिएबल" सिर्फ एक प्रतीक है जो किसी और चीज की ओर इशारा करता है। PHP में, यह आंतरिक रूप से एक "ज़वल" नामक किसी चीज़ की ओर इशारा करता है, जिसे वास्तव में एक साथ कई चर के लिए इस्तेमाल किया जा सकता है, या तो क्योंकि उनका एक ही मूल्य है (PHP कुछ ऐसा करता है जिसे "कॉपी-ऑन-राइट" कहा जाता है, ताकि $foo = $barइसकी आवश्यकता न हो अतिरिक्त मेमोरी को सीधे आवंटित करें) या क्योंकि उन्हें संदर्भ (उदाहरण के लिए $foo =& $bar) में असाइन किया गया है (या किसी फ़ंक्शन को पास किया गया है )। इसलिए एक अंचल का कोई नाम नहीं है।
  • जब आप किसी फ़ंक्शन को एक पैरामीटर पास करते हैं तो आप एक नया चर बना रहे हैं (भले ही यह एक संदर्भ हो)। आप कुछ अनाम, जैसे पास कर सकते हैं "hello", लेकिन एक बार अपने फ़ंक्शन के अंदर, यह जो भी चर है, उसे नाम दें। यह काफी कोड जुदाई के लिए मौलिक है: अगर एक समारोह क्या एक चर पर भरोसा इस्तेमाल किया नाम से जाना, यह अधिक एक जैसा होगा gotoएक ठीक से अलग समारोह की तुलना में।
  • वैश्विक चर को आमतौर पर एक बुरा विचार माना जाता है। यहां बहुत सारे उदाहरण यह मानते हैं कि जिस वेरिएबल को आप "प्रतिबिंबित" करना चाहते हैं वह इसमें पाया जा सकता है $GLOBALS, लेकिन यह केवल तभी सच होगा जब आपने अपने कोड को बुरी तरह से संरचित किया हो और चर किसी फ़ंक्शन या ऑब्जेक्ट के लिए स्कैन नहीं किए गए हों।
  • प्रोग्रामर उनके कोड को पढ़ने में मदद करने के लिए परिवर्तनीय नाम हैं। बेहतर उद्देश्य के लिए चर का नाम बदलना एक बहुत ही सामान्य रीफैक्टरिंग अभ्यास है, और पूरी बात यह है कि इससे कोई फर्क नहीं पड़ता है।

अब, मैं डिबगिंग के लिए इसके लिए इच्छा को समझता हूं (हालांकि कुछ प्रस्तावित usages इससे परे हैं), लेकिन एक सामान्यीकृत समाधान के रूप में यह वास्तव में उतना उपयोगी नहीं है जितना आप सोच सकते हैं: यदि आपका डिबग फ़ंक्शन कहता है कि आपका चर "$ फ़ाइल" है ", कि आपके कोड में अभी भी दर्जनों" $ फ़ाइल "चर में से कोई एक हो सकता है, या एक चर जिसे आपने" $ फ़ाइलनाम "कहा है, लेकिन एक फ़ंक्शन के पास जा रहे हैं जिसका पैरामीटर" $ फ़ाइल "कहा जाता है।

आपके कोड में डिबग फ़ंक्शन कहा गया था, जहां जानकारी का एक और अधिक उपयोगी टुकड़ा है। चूंकि आप इसे अपने संपादक में जल्दी से पा सकते हैं, आप देख सकते हैं कि आप किस चर को अपने लिए तैयार कर रहे थे, और पूरे भावों को एक बार में भी पास कर सकते हैं (जैसे debug('$foo + $bar = ' . ($foo + $bar)))।

उसके लिए, आप अपने डिबग फ़ंक्शन के शीर्ष पर इस स्निपेट का उपयोग कर सकते हैं:

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

कुछ अच्छे जवाब पहले से ही हैं। तो यह सिर्फ वास्तविकता के सामने भी निराशावादी हो रहा है।
a20

@ a20 सभी जवाबों के बारे में भारी चेतावनी है कि उनका उपयोग कब किया जा सकता है और वे कब टूटेंगे; कोई भी किसी भी चर से अपने नाम के लिए एक साधारण खोज नहीं है, क्योंकि यह वास्तव में असंभव है। कुछ डिबगिंग उद्देश्यों के लिए बहुत अधिक कायरतापूर्ण प्रतिबिंब करते हैं, जो ठीक है; हालाँकि, मेरी राय यह है कि आप लाइन नंबर के आउटपुट को बेहतर बना रहे हैं और स्वयं स्रोत की लाइन देख रहे हैं - या XDebug जैसे इंटरैक्टिव डिबगर का उपयोग कर रहे हैं।
IMSoP

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

संकेत अब आप समारोह नाम बदल सकते हैं और यह अभी भी काम करते हैं और यह भी एक लाइन में समारोह कई बार प्रयोग करेंगे! @Cliffordlife को धन्यवाद


3
कूल, इसके लिए धन्यवाद। मैंने $ pat लाइन को $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';इस तरह से थोड़ा संशोधित किया कि मुझे परवाह नहीं है कि इस डिबग फ़ंक्शन को क्या कहा जाता है, और मुझे ठीक वही मिलता है जो फ़ंक्शन में दिया जाता है यानी $ hello, या "hello" (मैंने वेरिएबल के लिए $ मिलान हटा दिया है में, एक ही पंक्ति में)
क्लिफर्डलाइफ

1
कोड का शानदार टुकड़ा! धन्यवाद! हालांकि, यह सभी मामलों में काम नहीं करता है। मेरे ubuntu 18.04 पर php 7.2.19 के साथ परीक्षण का परिणाम: कोड की एक ही पंक्ति पर कई बार उपयोग किए जाने पर काम नहीं करता है, भले ही यह एक या अलग-अलग अभिव्यक्तियों में उपयोग किया जाता हो, क्योंकि तब यह अंतिम चर के नाम को लौटाता है लाइन। यदि यह एक ही अभिव्यक्ति में उपयोग किया जाता है, लेकिन अलग-अलग लाइनों पर यह काम करता है। विभिन्न रेखाओं पर विभिन्न भावों में इसका उपयोग किया जाता है।
मैटी

1
यह भी कि फ़ंक्शन "var_dump" के बिना एक पंक्ति में होना चाहिए - संयोजन print_var_name, echo, var_dumpभेजने के साथ आउटपुट$variable); echo ' '; var_dump($variable
बीजी ब्रूनो

13

PHP.net पर लुकास ने यह जांचने के लिए एक विश्वसनीय तरीका प्रदान किया कि क्या कोई चर मौजूद है। अपने उदाहरण में, वह वैरिएबल्स के ग्लोबल वेरिएबल ऐरे (या स्कोप्ड ऐरे) की कॉपी के माध्यम से प्रसारित होता है, वैल्यू को रैंडमली जनरेट किए गए वैल्यू में बदलता है और कॉपी किए गए एरे में जनरेट वैल्यू की जांच करता है।

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


आप सरणी रूप में वर्तमान गुंजाइश कैसे प्राप्त करते हैं?
सेबेस्टियन ग्रिग्नोली

अच्छा! मेरे लिए केवल गायब है break;जब foreach + में बराबर पाया जाता है तो मैंने स्वचालित रूप से var_name प्राप्त करने के लिए स्वचालित रूप से प्राप्त करने के लिए उपयोग करने योग्य बुनियादी संरचना की थी। यदि आप अक्सर कॉपी और पेस्ट करते हैं या इसे बेहतर बनाने के लिए बेहतर विचार रखते हैं, तो उपयोग करेंvariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2

यह शायद काम करने का सबसे तेज़ और सबसे साफ तरीका है, डिबगिंग की संभावना में प्रदर्शन के मुद्दे शामिल हैं। फ़ंक्शन को बिना किसी रुकावट के केवल असाइन करने के बजाय फ़ॉरच लूप में सीधे लौटना चाहिए। GLOBALS को देखते हुए यह बड़ा हो सकता है कि प्रदर्शन में काफी सुधार हो सकता है।
जॉन

13

मैंने डिबगिंग कारणों के लिए एक निरीक्षण कार्य किया। यह स्टेरॉयड पर प्रिंट_आर () की तरह है, क्रुमो की तरह लेकिन वस्तुओं पर थोड़ा अधिक प्रभावी है। मैं var नाम का पता लगाना चाहता था और इस पेज पर निक प्रेस्टा की पोस्ट से प्रेरित होकर यह आया। यह एक तर्क के रूप में पारित किसी भी अभिव्यक्ति का पता लगाता है, न केवल चर नाम।

यह केवल रैपर फ़ंक्शन है जो पारित अभिव्यक्ति का पता लगाता है। अधिकांश मामलों पर काम करता है। यदि आप एक ही बार कोड की एक पंक्ति में फ़ंक्शन को कॉल करते हैं तो यह काम नहीं करेगा।

यह ठीक काम करता है: मर ( निरीक्षण)$ This-> getUser () -> hasCredential ( "हटाएँ")) );

निरीक्षण () फ़ंक्शन है जो पारित अभिव्यक्ति का पता लगाएगा।

हमें मिलता है: $ यह-> getUser () -> hasCredential ("हटाएं")

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

}

एक्शन में इंस्पेक्टर फंक्शन (और मेरी डीस्पेक्ट क्लास) का एक उदाहरण है:

http://inspect.ip1.cc

ग्रंथ उस पृष्ठ में स्पेनिश में हैं, लेकिन कोड संक्षिप्त है और वास्तव में समझने में आसान है।


1
इर्र्म, कि तुम पर भरोसा नहीं है कि NuSphare डिबगर स्थापित किया है?
मावग का कहना है कि मोनिका

मैंने वहां इस कोड का सरलीकृत संस्करण पोस्ट किया। इसके अलावा मैंने इस उत्तर को संशोधित किया है। यह अब हर PHP5 कार्यान्वयन पर चलना चाहिए।
सेबेस्टियन ग्रिग्नोली

इस तरह की सहजता इसीलिए मैं हर बार मुस्कुराता हूं, जिसे देखकर लोग कहते हैं कि "किया नहीं जा सकता" या "संभव नहीं", जिसमें इस मामले में खुद रासमस भी शामिल है। कुदोस से सेबेस्टियन और किसी और ने जो इस उत्तर में योगदान दिया हो।
नाइट उल्लू

1
धन्यवाद नाइट उल्लू, लेकिन मैं जोर देकर कहता हूं कि यह बुलेट प्रूफ नहीं है (जैसा कि उत्तर में कहा गया है, यह विफल होगा यदि मेरा "निरीक्षण ()" फ़ंक्शन एक ही पंक्ति में एक से अधिक बार कहा जाता है!)। मैं उत्पादन में इसका इस्तेमाल कभी नहीं करूंगा। यह केवल डिबगिंग इंस्पेक्टर फ़ंक्शन के लिए है जिसे कभी भी उत्पादन सर्वर तक नहीं पहुंचना चाहिए।
सेबेस्टियन ग्रिग्नोली

7

से php.net

@ अलेक्सांद्र - लघु समाधान

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

4

कई जवाब इस की उपयोगिता पर सवाल उठाते हैं। हालांकि, एक चर के लिए एक संदर्भ प्राप्त करना बहुत उपयोगी हो सकता है। विशेष रूप से वस्तुओं के मामले में और यह $ । मेरा समाधान वस्तुओं के साथ काम करता है, और संपत्ति परिभाषित वस्तुओं के रूप में भी:

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

कई चरों के लिए ऊपर दिए गए उत्तरों से अनुकूलित, अच्छे प्रदर्शन के साथ, कई के लिए सिर्फ एक $ 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

मेरे पास वास्तव में इसके लिए वैध उपयोग का मामला है।

मेरे पास एक फ़ंक्शन कैशवेरिबल ($ var) है (ठीक है, मेरे पास एक फ़ंक्शन कैश ($ कुंजी, $ मूल्य) है, लेकिन मैं एक फ़ंक्शन का उल्लेख करना चाहूंगा)।

उद्देश्य यह करना है:

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

लेकिन यह भी विफल ... :(

ज़रूर, मैं कैश ('रंग', $ रंग) करना जारी रख सकता हूं, लेकिन मैं आलसी हूं, आप जानते हैं ...;)

इसलिए, मैं जो चाहता हूं वह एक फ़ंक्शन है जो किसी वैरिएबल के मूल नाम को प्राप्त करता है, क्योंकि यह एक फ़ंक्शन को दिया गया था। फ़ंक्शन के अंदर ऐसा कोई तरीका नहीं है जिससे मैं यह जान पाऊं कि जैसा लगता है। उपरोक्त दूसरे उदाहरण में संदर्भ के आधार पर get_defined_vars () पास करने से मुझे कुछ मदद मिली (उस विचार के लिए जीन-जैक्स ग्यूगन के लिए धन्यवाद)। उत्तरार्द्ध समारोह ने काम करना शुरू कर दिया, लेकिन यह अभी भी केवल स्थानीय चर ('चर' को लौटाता रहा, 'रंग' को नहीं)।

मैंने अभी तक 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

आप केवल एक साधारण फ़ंक्शन और इसे TELL क्यों नहीं बनाते हैं?

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

इसे प्राप्त करने के लिए आप कॉम्पैक्ट () का उपयोग कर सकते हैं।

$FooBar = "a string";

$newArray = compact('FooBar');

यह कुंजी के रूप में चर नाम के साथ एक सहयोगी सरणी बनाएगा। आप तब कुंजी नाम का उपयोग करके सरणी के माध्यम से लूप कर सकते हैं जहां आपको इसकी आवश्यकता थी।

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

2
कूल लेकिन आपको इसका उपयोग करने के लिए चर का नाम जानना होगा। ओपी प्रोग्रामैटिक रूप से वेरिएबल नेम निर्धारित करने के लिए देख रहा है।
एक कोडर

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खाली है या अशक्त है, तो यह पहले खाली या अशक्त स्ट्रिंग के नाम को प्रिंट करेगा।

यह इस तरह के रूप में इस्तेमाल किया जा सकता है:

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 ));"डिफ़ॉल्ट" ग्लोबल्स की संख्या के बारे में एक गलत धारणा की तरह दिखता है। मेरी प्रणाली में सात सुपरग्लोबल हैं: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER। और argv और argc भी है। तो ऑफसेट 9. होना चाहिए और तीसरे पैरामीटर (लंबाई) को निर्दिष्ट करने का कोई मतलब नहीं है क्योंकि डिफ़ॉल्ट बस वैसे भी सरणी के अंत तक चलना है।
जेफ

-2

इसे त्वरित और गंदा माना जा सकता है, लेकिन मेरी अपनी व्यक्तिगत प्राथमिकता इस तरह से एक फ़ंक्शन / विधि का उपयोग करना है:

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

मूल रूप से यह एक साहचर्य सरणी बनाता है जिसमें एक अशक्त / खाली तत्व होता है, जिसका उपयोग उस कुंजी चर के रूप में किया जाता है जिसके लिए आप नाम चाहते हैं।

फिर हम array_keys का उपयोग करके उस कुंजी का मान प्राप्त करते हैं और उसे वापस करते हैं।

जाहिर है यह गड़बड़ हो जाता है और उत्पादन के माहौल में वांछनीय नहीं होगा, लेकिन यह प्रस्तुत समस्या के लिए काम करता है।


1
चर का मूल्य, चर का नाम नहीं है। जैसा कि कहीं और बताया गया है कि नाम समारोह सीमाओं के पार पोर्टेबल नहीं है।
ओवेन बेर्स्फोर्ड

3
माइनस एक क्योंकि यह फ़ंक्शन वस्तुतः ट्रिम ($ var) लौटाने के अलावा कुछ नहीं करता है;
अलेक्सर

-3

हमें चर नाम प्राप्त करने के लिए ग्लोबल्स का उपयोग क्यों करना है ... हम नीचे की तरह उपयोग कर सकते हैं।

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

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

6
क्योंकि ओपी को वेरिएबल नाम नहीं पता होता है। अगर वह करता, तो उसे एक getVarName()समारोह की आवश्यकता नहीं होती । ;-)
FtDRbwLXw6

1
यह स्ट्रिंग के रूप में एक चर का नाम नहीं लौटाता है, क्योंकि '$variableName'पहले से ही एक स्ट्रिंग है, न कि एक चर। यदि आप इस चाल के साथ कर सकते हैं getVarName($variableName);, तो आपको एक उत्थान मिल जाएगा :)
डैनियल डब्ल्यू।

-4

मैं वास्तव में उपयोग के मामले को देखने में विफल रहा हूँ ... यदि आप print_var_name ($ foobar) टाइप करेंगे तो इसके बजाय टाइपिंग प्रिंट ("foobar") के बारे में इतना कठिन (और अलग) क्या है?

क्योंकि यहां तक ​​कि अगर आप इसे एक समारोह में उपयोग करने के लिए थे, तो आपको चर का स्थानीय नाम मिलेगा ...

किसी भी मामले में, यहाँ प्रतिबिंब प्रतिबिंब के मामले में वहाँ कुछ है जिसकी आपको आवश्यकता है।


प्रिंट ("फ़ॉबर") अन्य वेरिएशन को हैंडल नहीं करेगा।
गैरी विल्बोबी

7
मामले का उपयोग करें: आपके पास कोड में कुछ डीबग पॉइंट हैं जो समान मान को डंपिंग लौटाते हैं। आपको कैसे पता चलेगा कि पहले किसको अंजाम दिया गया था? एक लेबल प्रिंट करना तब बहुत उपयोगी होता है।
ताकेशिन

तब आपने पर्याप्त प्रोग्रामिंग नहीं की है। ज्यादातर भाषाओं में मुझे ऐसा करने का कुछ तरीका है, आमतौर पर सरल है।
b01

@ b01 मैंने बहुत कुछ किया है। मैं पूरी तरह से जानता हूं कि ऐसी कई भाषाएं हैं जो इसे अनुमति देती हैं, लेकिन यह अपने आप में बहुत मायने नहीं रखती है। कई भाषाएं गोटो को आसानी से करने का कोई तरीका प्रदान करती हैं और इसका मतलब यह नहीं है कि आपको उचित प्रवाह नियंत्रण लिखने से बचने के लिए इसका उपयोग करना चाहिए। मेरे विचार में यह एक ऐसा ही मामला है। मुझे संदेह नहीं है कि उचित मामले हैं, और इसलिए मैं इसके लिए उचित उपयोग के मामलों के बारे में सोच रहा था।
विन्को वर्सालोविच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.