Jeśli potrzebujesz tego do czegoś innego niż debugowanie, robisz coś bardzo złego. Jaki jest twój przypadek użycia?
troelskn
10
Dobre pytanie. Potrzebowałem tego samego do debugowania.
trwa
17
+1 - Potrzebowałem tego do automatycznego generowania odpowiedzi XML lub JSON z modelowego obiektu PHP. Konieczność zawinięcia obiektu do innej nazwanej rootName => modelObjecttablicy po prostu dodaje niepotrzebnej głębi do odpowiedzi. Szkoda, że nie zostało to uwzględnione w możliwościach odzwierciedlania środowiska wykonawczego języka.
Anurag
4
Potrzebowałem tego również w funkcji logowania. Chciałem móc wykonać następujące czynności: log ($ didTheSystemBlowUp); Aby pojawić się w pliku dziennika, takim jak: $ didTheSystemBlowUp = „jeszcze nie, ale już wkrótce”;
SeanDowney
4
Może to również być przydatne podczas wywoływania var_dump (), więc gdy wywołujesz jednocześnie kilka zmiennych, nie masz ręcznie wypisywanej nazwy zmiennej, aby odróżnić wyjścia vardupms.
PHPst
Odpowiedzi:
37
Możesz użyć get_defined_vars (), aby znaleźć nazwę zmiennej, która ma taką samą wartość jak ta, dla której próbujesz znaleźć nazwę. Oczywiście nie zawsze będzie to działać, ponieważ różne zmienne często mają te same wartości, ale jest to jedyny sposób, w jaki mogę to zrobić.
Edycja: get_defined_vars () wydaje się nie działać poprawnie, zwraca „var”, ponieważ $ var jest używane w samej funkcji. $ GLOBALS wydaje się działać, więc zmieniłem to na to.
function print_var_name($var){foreach($GLOBALS as $var_name => $value){if($value === $var){return $var_name;}}returnfalse;}
Edycja: aby było jasne, nie ma dobrego sposobu na zrobienie tego w PHP, prawdopodobnie dlatego, że nie powinieneś tego robić. Prawdopodobnie są lepsze sposoby robienia tego, co próbujesz zrobić.
Ahh Byłem wolny ;-) Myślałem tak samo, ale zamiast tego użyłem $ GLOBALS. Tak więc porównanie tożsamości daje wartość true dla równych wartości skalarnych ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel
Właściwie teraz, kiedy przetestowałem mój kod, mój kod zawsze zwracał „var”, ponieważ jest używany w funkcji. Kiedy zamiast tego używam $ GLOBALS, zwraca ona z jakiegoś powodu poprawną nazwę zmiennej. Więc zmienię powyższy kod, aby używał $ GLOBALS.
Jeremy Ruten
Tak, zdałem sobie sprawę, ale get_defined_vars () wystarczyło ta.
Gary Willoughby,
2
Istnieje wiele przypadków, w których ten kod nie będzie działał zgodnie z oczekiwaniami.
troelskn
122
Ten kod jest NAPRAWDĘ niepoprawny. Sprawdzanie, czy zmienna jest taka sama jak zmienna wysłana przez VALUE, jest bardzo głupim pomysłem. Miriady zmiennych mają wartość NULL w dowolnym punkcie. Myriady są ustawione na 1. To jest po prostu szalone.
Alex Weinstein,
49
Nie mogłem wymyślić sposobu, aby zrobić to skutecznie, ale wpadłem na to. Działa, dla ograniczonych zastosowań poniżej.
Działa w oparciu o linię, która wywołała funkcję, w której znajduje przekazany argument. Przypuszczam, że można go rozszerzyć do pracy z wieloma argumentami, ale, jak powiedzieli inni, gdyby można lepiej wyjaśnić sytuację, inne rozwiązanie prawdopodobnie Pracuj lepiej.
Pracowałem z systemem, który intensywnie wykorzystywał zmienne zmienne. Ostrzegam cię, robi się naprawdę śmierdzący naprawdę szybko!
Icode4food,
3
w większości przypadków użytkownik chce uzyskać nazwę i wartość var. pomyśl „function debugvar ($ varname)”, a on zamierza nazwać to „debugvar („ foo ”)”, więc debugowanie wyświetli „foo = 123”. ze zmienną zmienną dostaną „foo” jest niezdefiniowany.
gcb
po prostu spójrz na to, co faktycznie robisz. Właśnie w tym przykładzie faktycznie UTWÓRZ zmienną $FooBaro wartości a stringpo prostu przeczytaj instrukcję. To okropne imho. nigdy nie przypisujesz zmiennej $FooBarwartości, ale ona tam jest. OUCH
Toskan
20
Wydaje się, że nikt nie wymienił podstawowych powodów, dla których jest to a) trudne i b) nierozsądne:
„Zmienna” to tylko symbol wskazujący na coś innego. W PHP wewnętrznie wskazuje na coś, co nazywa się „zval”, które może faktycznie być używane dla wielu zmiennych jednocześnie, ponieważ mają one tę samą wartość (PHP implementuje coś, co nazywa się „kopiuj przy zapisie”, więc $foo = $barnie trzeba alokuj dodatkową pamięć od razu) lub ponieważ zostały one przypisane (lub przekazane do funkcji) przez odniesienie (np $foo =& $bar.). Więc zval nie ma nazwy.
Gdy przekazujesz parametr do funkcji, tworzysz nową zmienną (nawet jeśli jest to odwołanie). Możesz przekazać coś anonimowego, "hello"ale gdy znajdziesz się w swojej funkcji, jest to jakakolwiek zmienna, którą nazwiesz. Jest to dość fundamentalne dla oddzielenia kodu: jeśli funkcja oparła się na tym, co zmienne wykorzystywane nazywać, to byłoby bardziej jakgoto niż odpowiednio oddzielnej funkcji.
Zmienne globalne są ogólnie uważane za zły pomysł. Wiele przykładów zakłada, że można znaleźć zmienną, którą chcesz „odzwierciedlić”$GLOBALS , ale będzie to prawdą tylko wtedy, gdy źle skonstruujesz swój kod, a zmienne nie będą miały zakresu do jakiejś funkcji lub obiektu.
Istnieją zmienne nazwy, aby pomóc programistom odczytać ich kod. Zmiana nazw zmiennych, aby lepiej pasowały do ich celów, jest bardzo powszechną praktyką refaktoryzacji, a cała sprawa polega na tym, że nie robi to żadnej różnicy.
Rozumiem teraz potrzebę debugowania (chociaż niektóre z proponowanych zastosowań wykraczają daleko poza to), ale jako ogólne rozwiązanie nie jest tak pomocne, jak mogłoby się wydawać: jeśli funkcja debugowania mówi, że twoja zmienna nosi nazwę „$ file ”, wciąż może to być dowolna z kilkudziesięciu zmiennych„ $ file ”w twoim kodzie lub zmienna, którą nazwałeś„ $ filename ”, ale przekazujesz do funkcji, której parametr nazywa się„ $ file ”.
O wiele bardziej użyteczną informacją jest to, skąd w kodzie została wywołana funkcja debugowania. Ponieważ możesz szybko znaleźć to w swoim edytorze, możesz zobaczyć, którą zmienną wypisałeś dla siebie, a nawet przesłać do niej całe wyrażenia za jednym razem (np debug('$foo + $bar = ' . ($foo + $bar)).).
W tym celu możesz użyć tego fragmentu u góry funkcji debugowania:
$backtrace = debug_backtrace();
echo '# Debug function called from '. $backtrace[0]['file'].' at line '. $backtrace[0]['line'];
Istnieje już kilka dobrych odpowiedzi. Jest to więc tylko pesymizm, nawet w obliczu rzeczywistości.
a20
@ a20 Wszystkie odpowiedzi mają poważne zastrzeżenia, kiedy można je wykorzystać i kiedy się złamią; żadna nie jest prostym wyszukiwaniem dowolnej zmiennej do jej nazwy, ponieważ w rzeczywistości jest to niemożliwe. Niektóre wykonują wiele funky refleksji w celu debugowania, co jest w porządku; jednak moim zdaniem lepiej jest po prostu wypisać numer linii i samemu wyszukać linię źródła lub użyć interaktywnego debuggera, takiego jak XDebug.
IMSoP
14
To jest dokładnie to, czego chcesz - jest to gotowa do użycia funkcja „kopiuj i upuszczaj”, która odzwierciedla nazwę danego 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);}
WYKORZYSTANIE: print_var_name ($ FooBar)
DRUKUJ: FooBar
WSKAZÓWKA
Teraz możesz zmienić nazwę funkcji i będzie ona nadal działać, a także korzystać z funkcji kilka razy w jednym wierszu! Dzięki @Cliffordlife
Fajnie, dzięki za to. Zmodyfikowałem nieco linię $ pat w $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';ten sposób, nie obchodzi mnie, jak nazywa się ta funkcja debugowania, i otrzymuję dokładnie to, co jest przekazywane do funkcji, tj. $ Hello lub „hello” (upuściłem dopasowanie $ dla przekazanej zmiennej w, w tej samej linii)
Cliffordlife
1
Fantastyczny kawałek kodu! Dzięki! Wydaje się jednak, że nie działa we wszystkich przypadkach. Wynik testowania na moim Ubuntu 18.04 z php 7.2.19: Nie działa, gdy jest używany wiele razy w tym samym wierszu kodu, niezależnie od tego, czy jest używany w jednym czy w osobnych wyrażeniach, ponieważ wtedy zwraca nazwę ostatniej zmiennej linia. Jeśli jest używany w tym samym wyrażeniu, ale w osobnych wierszach, działa. Działa w różnych wyrażeniach na różnych liniach.
Matty,
1
także ta funkcja powinna znajdować się w jednym wierszu bez „var_dump” - z połączonym print_var_name, echo, var_dumpwyjściem wysyłania$variable); echo ' '; var_dump($variable
BG Bruno
13
Lucas na PHP.net zapewnił niezawodny sposób sprawdzenia, czy zmienna istnieje. W swoim przykładzie iteruje przez kopię globalnej tablicy zmiennych (lub tablicy o zasięgu) zmiennych, zmienia wartość na losowo wygenerowaną wartość i sprawdza wygenerowaną wartość w skopiowanej tablicy.
Miły! Dla mnie brakuje tylko break;gdy jest równy w foreach + Zrobiłem użyteczną podstawową strukturę, aby automatycznie uzyskać var_name, jeśli zdefiniowano ją w funkcji. Jeśli często variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
kopiujesz i wklejasz
Jest to prawdopodobnie najszybszy i najczystszy sposób wykonania zadania, debugowanie prawdopodobnie obejmuje problemy z wydajnością. Funkcja powinna powrócić bezpośrednio w pętli foreach zamiast po prostu przypisywać bez zakłóceń. Biorąc pod uwagę, że GLOBALS może być duży, co może stanowić znaczną poprawę wydajności.
Jan
13
Z przyczyn debugowania wykonałem funkcję inspekcji. To jest jak print_r () na sterydach, podobnie jak Krumo, ale trochę bardziej skuteczne na obiektach. Chciałem dodać wykrywanie nazw var i wymyśliłem to, zainspirowany postem Nicka Presty na tej stronie. Wykrywa każde wyrażenie przekazane jako argument, nie tylko nazwy zmiennych.
Jest to tylko funkcja opakowania, która wykrywa przekazane wyrażenie. Działa w większości przypadków. Nie zadziała, jeśli wywołasz funkcję więcej niż jeden raz w tym samym wierszu kodu.
Działa to dobrze: die ( inspect ($ this-> getUser () -> hasCredential („delete”)) );
inspect () to funkcja, która wykryje przekazane wyrażenie.
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);}
Oto przykład funkcji inspektora (i mojej klasy dInspect) w akcji:
errrm, czy to nie zależy od tego, czy masz zainstalowany debuger NuSphare?
Mawg mówi o przywróceniu Moniki
Umieściłem tam uproszczoną wersję tego kodu. Zmodyfikowałem również tę odpowiedź. Powinien działać teraz na każdej implementacji PHP5.
Sebastián Grignoli
Dzięki takiej pomysłowości uśmiecham się za każdym razem, gdy widzę, jak ludzie mówią: „nie da się tego zrobić” lub „nie jest możliwe”, w tym nawet samego Rasmusa. Uznanie dla Sebastiana i każdego, kto mógł przyczynić się do tej odpowiedzi.
Night Owl
1
Dzięki Night Owl, ale nalegam, aby to nie było kuloodporne (jak mówi odpowiedź, nie powiedzie się, jeśli moja funkcja „inspect ()” zostanie wywołana więcej niż raz w jednym wierszu!). Nigdy nie użyłbym tego w produkcji. Dotyczy tylko funkcji inspektora debugowania, która nigdy nie powinna dotrzeć do serwera produkcyjnego.
<?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
{publicfunction __constructor(){
$this->my_object_property ="My object property string.";}}
$obj =new myclass;
echo vname($obj->my_object_property, $obj);// Outputs: my_object_property?>
Wiele odpowiedzi kwestionuje przydatność tego. Jednak uzyskanie odniesienia do zmiennej może być bardzo przydatne. Zwłaszcza w przypadku przedmiotów i $ this . Moje rozwiązanie działa z obiektami, a także jako obiekty zdefiniowane we właściwościach:
Jeśli zmienna jest wymienne, trzeba mieć logiki gdzieś , że jest rozstrzygający, która zmienna przyzwyczaja. Wszystko, co musisz zrobić, to wpisać nazwę zmiennej$variable tej logice, podczas gdy robisz wszystko inne.
Myślę, że trudno nam zrozumieć, do czego jest to potrzebne. Przykładowy kod lub wyjaśnienie tego, czego rzeczywiście próbuje zrobić może pomóc, ale podejrzewam, że jesteś drogą, sposobem overthinking to.
Mam funkcję cacheVariable ($ var) (ok, mam pamięć podręczną funkcji ($ key, $ value), ale chciałbym mieć funkcję, jak wspomniano).
Celem jest wykonanie:
$colour ='blue';
cacheVariable($colour);
...
// another session
...
$myColour = getCachedVariable('colour');
Próbowałem z
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}
Jasne, mógłbym nadal robić pamięć podręczną („kolor”, $ kolor), ale jestem leniwy, wiesz ...;)
Tak więc, czego chcę, to funkcja, która otrzymuje ORYGINALNĄ nazwę zmiennej, tak jak została przekazana do funkcji. Wewnątrz funkcji nie ma możliwości, żeby to wiedzieć, jak się wydaje. Przekazywanie get_defined_vars () przez odniesienie w drugim powyższym przykładzie pomogło mi (dzięki Jean-Jacquesowi Gueganowi za ten pomysł) nieco. Ta ostatnia funkcja zaczęła działać, ale nadal zwracała tylko zmienną lokalną („zmienna”, a nie „kolor”).
Nie próbowałem jeszcze używać get_func_args () i get_func_arg (), $ {} - kombinacje konstrukcji i key (), ale przypuszczam, że to też się nie powiedzie.
Podstawowym problemem jest przekazywanie wartości do funkcji, a nie zmiennych . Zmienne są tymczasowe i specyficzne dla ich zakresu. Często nazwa zmiennej może nie być kluczem, pod którym chcesz buforować wartość, i często i tak przywrócisz zmienną o innej nazwie (jak w twoim przykładzie). Jeśli naprawdę jesteś zbyt leniwy, aby powtórzyć nazwę klucza, aby zapamiętać zmienną, użyj cacheVariable(compact('color')).
Istniejąca funkcja wyświetla żółte pole z czerwonym konturem i pokazuje każdą zmienną według nazwy i wartości. Rozwiązanie tablicowe działa, ale jest trochę skomplikowane w pisaniu, gdy jest potrzebne.
To mój przypadek użycia i tak, ma to związek z debugowaniem. Zgadzam się z tymi, którzy kwestionują jego użycie w inny sposób.
Spowoduje to utworzenie tablicy asocjacyjnej z nazwą zmiennej jako kluczem. Następnie możesz zapętlić tablicę, używając nazwy klucza tam, gdzie jest to potrzebne.
Znacznie wolniej niż zwykłe metody deklarowania zmiennych.
David Spector,
0
Wiem, że to jest stare i już odpowiedziałem, ale tak naprawdę tego szukałem. Publikuję tę odpowiedź, aby zaoszczędzić trochę czasu na dopracowaniu niektórych odpowiedzi.
Jeśli $FooBarma unikalną wartość, wypisze „FooBar”. Jeśli$FooBar jest pusty lub zerowy, wypisze nazwę pierwszego znalezionego pustego lub zerowego ciągu.
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 valuereturn $name;}
Stosowanie
$city ="San Francisco";
echo getVar($city);// city
Uwaga: niektóre wersje PHP 7 nie będzie działać prawidłowo z powodu błędu w array_searchze $GLOBALSjednak wszystkie inne wersje będą działać.
@IMSoP Sądząc po wynikach print implode( ' ', array_keys( $GLOBALS ));, wygląda to na błędne założenie o liczbie „domyślnych” globali. W moim systemie jest siedem superglobali: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Są też argumenty argv i argc. Zatem przesunięcie powinno wynosić 9. I nie ma sensu określać trzeciego parametru (długości), ponieważ domyślnie i tak biegnie on do końca tablicy.
Jeff
-2
Może to być uważane za szybkie i brudne, ale moje osobiste preferencje to używanie funkcji / metody takiej jak ta:
Ponieważ OP nie zna nazwy zmiennej. Gdyby to zrobił, nie potrzebowałby getVarName()funkcji. ;-)
FtDRbwLXw6
1
To nie zwraca nazwy zmiennej jako ciągu, ponieważ '$variableName'jest już ciągiem, a nie zmienną. Jeśli potrafisz zrobić tę sztuczkę getVarName($variableName);, zyskujesz przychylność :)
Daniel W.
-4
Naprawdę nie widzę przypadku użycia ... Jeśli wpiszesz print_var_name ($ foobar), co jest tak trudne (i inne) w pisaniu print („foobar”) zamiast tego?
Ponieważ nawet gdybyś używał tego w funkcji, uzyskałbyś lokalną nazwę zmiennej ...
Tak czy inaczej, oto instrukcja refleksji na wypadek, gdybyś czegoś potrzebował.
Drukuj („foobar”) nie będzie obsługiwać innych zmiennych.
Gary Willoughby,
7
Przypadek użycia: masz kilka punktów debugowania w kodzie zwracających zrzut tej samej wartości. Skąd wiesz, który został najpierw wykonany? Drukowanie etykiety jest wtedy bardzo przydatne.
bierze
Więc nie zrobiłeś wystarczająco dużo programowania. Większość języków, z którymi się spotkałem, ma na to jakiś sposób, zwykle prosty.
b01
@ b01 Zrobiłem dużo. Wiem doskonale, że istnieje wiele języków, które na to pozwalają, ale to samo w sobie niewiele znaczy. Wiele języków oferuje sposób łatwego wykonywania goto, co nie oznacza, że powinieneś go używać, aby uniknąć pisania odpowiedniej kontroli przepływu. Jest to moim zdaniem podobny przypadek. Nie wątpię, że istnieją uzasadnione przypadki i dlatego zastanawiałem się nad odpowiednimi przypadkami użycia.
rootName => modelObject
tablicy po prostu dodaje niepotrzebnej głębi do odpowiedzi. Szkoda, że nie zostało to uwzględnione w możliwościach odzwierciedlania środowiska wykonawczego języka.Odpowiedzi:
Możesz użyć get_defined_vars (), aby znaleźć nazwę zmiennej, która ma taką samą wartość jak ta, dla której próbujesz znaleźć nazwę. Oczywiście nie zawsze będzie to działać, ponieważ różne zmienne często mają te same wartości, ale jest to jedyny sposób, w jaki mogę to zrobić.
Edycja: get_defined_vars () wydaje się nie działać poprawnie, zwraca „var”, ponieważ $ var jest używane w samej funkcji. $ GLOBALS wydaje się działać, więc zmieniłem to na to.
Edycja: aby było jasne, nie ma dobrego sposobu na zrobienie tego w PHP, prawdopodobnie dlatego, że nie powinieneś tego robić. Prawdopodobnie są lepsze sposoby robienia tego, co próbujesz zrobić.
źródło
Nie mogłem wymyślić sposobu, aby zrobić to skutecznie, ale wpadłem na to. Działa, dla ograniczonych zastosowań poniżej.
wzruszać ramionami
Działa w oparciu o linię, która wywołała funkcję, w której znajduje przekazany argument. Przypuszczam, że można go rozszerzyć do pracy z wieloma argumentami, ale, jak powiedzieli inni, gdyby można lepiej wyjaśnić sytuację, inne rozwiązanie prawdopodobnie Pracuj lepiej.
źródło
Czy możesz rozważyć zmianę podejścia i użycie nazwy zmiennej?
wtedy możesz po prostu
dostać
Oto link do instrukcji PHP na temat zmiennych zmiennych
źródło
$FooBar
o wartościa string
po prostu przeczytaj instrukcję. To okropne imho. nigdy nie przypisujesz zmiennej$FooBar
wartości, ale ona tam jest. OUCHWydaje się, że nikt nie wymienił podstawowych powodów, dla których jest to a) trudne i b) nierozsądne:
$foo = $bar
nie trzeba alokuj dodatkową pamięć od razu) lub ponieważ zostały one przypisane (lub przekazane do funkcji) przez odniesienie (np$foo =& $bar
.). Więc zval nie ma nazwy."hello"
ale gdy znajdziesz się w swojej funkcji, jest to jakakolwiek zmienna, którą nazwiesz. Jest to dość fundamentalne dla oddzielenia kodu: jeśli funkcja oparła się na tym, co zmienne wykorzystywane nazywać, to byłoby bardziej jakgoto
niż odpowiednio oddzielnej funkcji.$GLOBALS
, ale będzie to prawdą tylko wtedy, gdy źle skonstruujesz swój kod, a zmienne nie będą miały zakresu do jakiejś funkcji lub obiektu.Rozumiem teraz potrzebę debugowania (chociaż niektóre z proponowanych zastosowań wykraczają daleko poza to), ale jako ogólne rozwiązanie nie jest tak pomocne, jak mogłoby się wydawać: jeśli funkcja debugowania mówi, że twoja zmienna nosi nazwę „$ file ”, wciąż może to być dowolna z kilkudziesięciu zmiennych„ $ file ”w twoim kodzie lub zmienna, którą nazwałeś„ $ filename ”, ale przekazujesz do funkcji, której parametr nazywa się„ $ file ”.
O wiele bardziej użyteczną informacją jest to, skąd w kodzie została wywołana funkcja debugowania. Ponieważ możesz szybko znaleźć to w swoim edytorze, możesz zobaczyć, którą zmienną wypisałeś dla siebie, a nawet przesłać do niej całe wyrażenia za jednym razem (np
debug('$foo + $bar = ' . ($foo + $bar))
.).W tym celu możesz użyć tego fragmentu u góry funkcji debugowania:
źródło
To jest dokładnie to, czego chcesz - jest to gotowa do użycia funkcja „kopiuj i upuszczaj”, która odzwierciedla nazwę danego var:
WYKORZYSTANIE: print_var_name ($ FooBar)
DRUKUJ: FooBar
źródło
$pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
ten sposób, nie obchodzi mnie, jak nazywa się ta funkcja debugowania, i otrzymuję dokładnie to, co jest przekazywane do funkcji, tj. $ Hello lub „hello” (upuściłem dopasowanie $ dla przekazanej zmiennej w, w tej samej linii)print_var_name, echo, var_dump
wyjściem wysyłania$variable); echo ' '; var_dump($variable
Lucas na PHP.net zapewnił niezawodny sposób sprawdzenia, czy zmienna istnieje. W swoim przykładzie iteruje przez kopię globalnej tablicy zmiennych (lub tablicy o zasięgu) zmiennych, zmienia wartość na losowo wygenerowaną wartość i sprawdza wygenerowaną wartość w skopiowanej tablicy.
Więc spróbuj:
Pamiętaj, aby sprawdzić jego post na PHP.net: http://php.net/manual/en/language.variables.php
źródło
break;
gdy jest równy w foreach + Zrobiłem użyteczną podstawową strukturę, aby automatycznie uzyskać var_name, jeśli zdefiniowano ją w funkcji. Jeśli częstovariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
Z przyczyn debugowania wykonałem funkcję inspekcji. To jest jak print_r () na sterydach, podobnie jak Krumo, ale trochę bardziej skuteczne na obiektach. Chciałem dodać wykrywanie nazw var i wymyśliłem to, zainspirowany postem Nicka Presty na tej stronie. Wykrywa każde wyrażenie przekazane jako argument, nie tylko nazwy zmiennych.
Jest to tylko funkcja opakowania, która wykrywa przekazane wyrażenie. Działa w większości przypadków. Nie zadziała, jeśli wywołasz funkcję więcej niż jeden raz w tym samym wierszu kodu.
Działa to dobrze: die ( inspect ($ this-> getUser () -> hasCredential („delete”)) );
inspect () to funkcja, która wykryje przekazane wyrażenie.
Otrzymujemy: $ this-> getUser () -> hasCredential („delete”)
Oto przykład funkcji inspektora (i mojej klasy dInspect) w akcji:
http://inspect.ip1.cc
Na tej stronie teksty są w języku hiszpańskim, ale kod jest zwięzły i bardzo łatwy do zrozumienia.
źródło
Z php.net
@Alexandre - krótkie rozwiązanie
@Lucas - wykorzystanie
źródło
Wiele odpowiedzi kwestionuje przydatność tego. Jednak uzyskanie odniesienia do zmiennej może być bardzo przydatne. Zwłaszcza w przypadku przedmiotów i $ this . Moje rozwiązanie działa z obiektami, a także jako obiekty zdefiniowane we właściwościach:
Przykład powyższego:
źródło
Na podstawie powyższych odpowiedzi dla wielu zmiennych, z dobrą wydajnością, tylko jeden skan $ GLOBALS dla wielu
źródło
Jeśli zmienna jest wymienne, trzeba mieć logiki gdzieś , że jest rozstrzygający, która zmienna przyzwyczaja. Wszystko, co musisz zrobić, to wpisać nazwę zmiennej
$variable
tej logice, podczas gdy robisz wszystko inne.Myślę, że trudno nam zrozumieć, do czego jest to potrzebne. Przykładowy kod lub wyjaśnienie tego, czego rzeczywiście próbuje zrobić może pomóc, ale podejrzewam, że jesteś drogą, sposobem overthinking to.
źródło
Mam do tego ważny przypadek użycia.
Mam funkcję cacheVariable ($ var) (ok, mam pamięć podręczną funkcji ($ key, $ value), ale chciałbym mieć funkcję, jak wspomniano).
Celem jest wykonanie:
...
...
Próbowałem z
Próbowałem też z
Ale to też się nie udaje ... :(
Jasne, mógłbym nadal robić pamięć podręczną („kolor”, $ kolor), ale jestem leniwy, wiesz ...;)
Tak więc, czego chcę, to funkcja, która otrzymuje ORYGINALNĄ nazwę zmiennej, tak jak została przekazana do funkcji. Wewnątrz funkcji nie ma możliwości, żeby to wiedzieć, jak się wydaje. Przekazywanie get_defined_vars () przez odniesienie w drugim powyższym przykładzie pomogło mi (dzięki Jean-Jacquesowi Gueganowi za ten pomysł) nieco. Ta ostatnia funkcja zaczęła działać, ale nadal zwracała tylko zmienną lokalną („zmienna”, a nie „kolor”).
Nie próbowałem jeszcze używać get_func_args () i get_func_arg (), $ {} - kombinacje konstrukcji i key (), ale przypuszczam, że to też się nie powiedzie.
źródło
cacheVariable(compact('color'))
.Mam to:
Wolałbym to:
Istniejąca funkcja wyświetla żółte pole z czerwonym konturem i pokazuje każdą zmienną według nazwy i wartości. Rozwiązanie tablicowe działa, ale jest trochę skomplikowane w pisaniu, gdy jest potrzebne.
To mój przypadek użycia i tak, ma to związek z debugowaniem. Zgadzam się z tymi, którzy kwestionują jego użycie w inny sposób.
źródło
Oto moje rozwiązanie oparte na
Jeremy Ruten
Użyj tego
źródło
Dlaczego po prostu nie zbudujesz prostej funkcji i nie powiesz jej?
źródło
Szukałem tego, ale po prostu postanowiłem przekazać nazwę, zwykle i tak mam ją w schowku.
źródło
Aby to osiągnąć, możesz użyć compact ().
Spowoduje to utworzenie tablicy asocjacyjnej z nazwą zmiennej jako kluczem. Następnie możesz zapętlić tablicę, używając nazwy klucza tam, gdzie jest to potrzebne.
źródło
Myślę, że chcesz znać nazwę zmiennej z jej wartością. Aby to osiągnąć, możesz użyć tablicy asocjacyjnej.
użyj nazw zmiennych dla kluczy tablicy:
Gdy chcesz uzyskać nazwy zmiennych, użyj
array_keys($vars)
, zwróci tablicę tych nazw zmiennych, które były używane w$vars
tablicy jako klucze.źródło
Wiem, że to jest stare i już odpowiedziałem, ale tak naprawdę tego szukałem. Publikuję tę odpowiedź, aby zaoszczędzić trochę czasu na dopracowaniu niektórych odpowiedzi.
Opcja 1:
Wydruki:
Z jakiegokolwiek powodu znajdziesz się w takiej sytuacji, to faktycznie działa.
.
Opcja 2:
Jeśli
$FooBar
ma unikalną wartość, wypisze „FooBar”. Jeśli$FooBar
jest pusty lub zerowy, wypisze nazwę pierwszego znalezionego pustego lub zerowego ciągu.Może być używany jako taki:
źródło
Tak to zrobiłem
Stosowanie
Uwaga: niektóre wersje PHP 7 nie będzie działać prawidłowo z powodu błędu w
array_search
ze$GLOBALS
jednak wszystkie inne wersje będą działać.Zobacz https://3v4l.org/UMW7V
źródło
Użyj tego, aby odłączyć zmienne użytkownika od globalnego i sprawdzić zmienną w danym momencie.
źródło
print implode( ' ', array_keys( $GLOBALS ));
, wygląda to na błędne założenie o liczbie „domyślnych” globali. W moim systemie jest siedem superglobali: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Są też argumenty argv i argc. Zatem przesunięcie powinno wynosić 9. I nie ma sensu określać trzeciego parametru (długości), ponieważ domyślnie i tak biegnie on do końca tablicy.Może to być uważane za szybkie i brudne, ale moje osobiste preferencje to używanie funkcji / metody takiej jak ta:
po prostu tworzy tablicę asocjacyjną zawierającą jeden pusty element, wykorzystując jako klucz zmienną, dla której chcesz nazwać.
następnie otrzymujemy wartość tego klucza za pomocą array_keys i zwracamy go.
oczywiście robi się to szybko bałagan i nie byłoby pożądane w środowisku produkcyjnym, ale działa na przedstawiony problem.
źródło
dlaczego musimy używać globałów, aby uzyskać nazwę zmiennej ... możemy użyć po prostu jak poniżej.
źródło
getVarName()
funkcji. ;-)'$variableName'
jest już ciągiem, a nie zmienną. Jeśli potrafisz zrobić tę sztuczkęgetVarName($variableName);
, zyskujesz przychylność :)Naprawdę nie widzę przypadku użycia ... Jeśli wpiszesz print_var_name ($ foobar), co jest tak trudne (i inne) w pisaniu print („foobar”) zamiast tego?
Ponieważ nawet gdybyś używał tego w funkcji, uzyskałbyś lokalną nazwę zmiennej ...
Tak czy inaczej, oto instrukcja refleksji na wypadek, gdybyś czegoś potrzebował.
źródło