Jak przechwycić wynik var_dump do ciągu?

605

Chciałbym uchwycić wyjście var_dumpdo ciągu.

Dokumentacja PHP mówi;

Podobnie jak w przypadku wszystkiego, co wysyła wynik bezpośrednio do przeglądarki, funkcje kontroli wyjścia mogą być wykorzystane do przechwycenia wyniku tej funkcji i zapisania go w ciągu (na przykład).

Jaki byłby przykład tego, jak to może działać?

print_r() nie jest prawidłową możliwością, ponieważ nie dostarczy mi potrzebnych informacji.

Mark Biek
źródło

Odpowiedzi:

601

Użyj buforowania wyjściowego:

<?php
ob_start();
var_dump($someVar);
$result = ob_get_clean();
?>
Eran Galperin
źródło
8
Korzystanie z buforowania wyjściowego najprawdopodobniej będzie miało negatywny wpływ na wydajność. Może również stać się bardzo niechlujny, jeśli trzeba spojrzeć na wiele zmiennych podczas wykonywania złożonego skryptu.
selfawaresoup
83
@Inwdr Używałem tylko var_dump jako wygodnej funkcji do debugowania i na pewno nigdy nie zostawiłem instrukcji var_dump w kodzie produkcyjnym. Wyobrażam sobie, że to typowe. W tych okolicznościach wydajność prawdopodobnie nie będzie istotna.
Mark Amery
usuń również tagi dla czytelności (jeśli chcesz tylko ciąg), używając strip_tags(), to po prostu zwróci typ i wartość.
Anil,
11
To dobra dosłowna odpowiedź na pytanie, ponieważ „chwytasz [wynik] var_dump do łańcucha” dokładnie tak, jak zostało zadane. var_export () jest lepszą odpowiedzią w duchu, ponieważ ogólnie ma większy sens.
Josh z Qaribou
1
@AlbertHendriks Wolę var_dump. Po włączeniu Xdebug uzyskujesz ładne wyświetlanie danych.
robsch
880

Próbować var_export

Możesz to sprawdzić var_export- chociaż nie zapewnia tego samego wyniku, ponieważ var_dumpzapewnia drugi $returnparametr, który spowoduje, że zwróci on wynik, zamiast go wydrukować:

$debug = var_export($my_var, true);

Dlaczego?

Wolę ten jednowarstwowy od używania ob_starti ob_get_clean(). Uważam również, że wynik jest nieco łatwiejszy do odczytania, ponieważ jest to po prostu kod PHP.

Różnica między var_dumpi var_exportpolega na tym, że var_exportzwraca „reprezentatywny ciąg znaków zmiennej”, a var_dumppo prostu zrzuca informacje o zmiennej. W praktyce oznacza to, że var_exportdaje ci prawidłowy kod PHP (ale może nie dawać ci tyle informacji o zmiennej, szczególnie jeśli pracujesz z zasobami ).

Próbny:

$demo = array(
    "bool" => false,
    "int" => 1,
    "float" => 3.14,
    "string" => "hello world",
    "array" => array(),
    "object" => new stdClass(),
    "resource" => tmpfile(),
    "null" => null,
);

// var_export -- nice, one-liner
$debug_export = var_export($demo, true);

// var_dump
ob_start();
var_dump($demo);
$debug_dump = ob_get_clean();

// print_r -- included for completeness, though not recommended
$debug_printr = print_r($demo, true);

Różnica w wydajności:

var_export ( $debug_exportw powyższym przykładzie):

 array (
  'bool' => false,
  'int' => 1,
  'float' => 3.1400000000000001,
  'string' => 'hello world',
  'array' => 
  array (
  ),
  'object' => 
  stdClass::__set_state(array(
  )),
  'resource' => NULL, // Note that this resource pointer is now NULL
  'null' => NULL,
)

var_dump ( $debug_dumpw powyższym przykładzie):

 array(8) {
  ["bool"]=>
  bool(false)
  ["int"]=>
  int(1)
  ["float"]=>
  float(3.14)
  ["string"]=>
  string(11) "hello world"
  ["array"]=>
  array(0) {
  }
  ["object"]=>
  object(stdClass)#1 (0) {
  }
  ["resource"]=>
  resource(4) of type (stream)
  ["null"]=>
  NULL
}

print_r ( $debug_printrw powyższym przykładzie):

Array
(
    [bool] => 
    [int] => 1
    [float] => 3.14
    [string] => hello world
    [array] => Array
        (
        )

    [object] => stdClass Object
        (
        )

    [resource] => Resource id #4
    [null] => 
)

Zastrzeżenie: var_exportnie obsługuje referencji okrągłych

Jeśli próbujesz zrzucić zmienną z referencjami cyklicznymi, wywołanie var_exportspowoduje ostrzeżenie PHP:

 $circular = array();
 $circular['self'] =& $circular;
 var_export($circular);

Prowadzi do:

 Warning: var_export does not handle circular references in example.php on line 3
 array (
   'self' => 
   array (
     'self' => NULL,
   ),
 )

Zarówno , jak var_dumpi print_r, z drugiej strony, wyprowadzi ciąg, *RECURSION*gdy napotka okrągłe odwołania.

inxilpro
źródło
11
To zdecydowanie lepsza odpowiedź niż zaakceptowana. Dziwi mnie, że nie ma więcej pozytywnych opinii! Czy mógłbyś wyjaśnić, dlaczego może nie dostarczyć wszystkich informacji, których szuka?
JMTyler
7
@JMTyler var_export zwraca analizowalny ciąg - zasadniczo kod PHP - podczas gdy var_dump zapewnia surowy zrzut danych. Na przykład, jeśli wywołasz var_dump na liczbie całkowitej o wartości 1, zostanie wydrukowany, int(1)podczas gdy var_export po prostu wydrukuje 1.
inxilpro
4
var_export ląduje na brzuchu, jeśli używasz go z $ GLOBALS, podczas gdy var_dump działa.
Olaf
3
nie będzie działać ze zmiennymi zawierającymi odniesienia do siebie. var_export nie działa jak var_dump; w ten sposób $ v = []; $ v [] = & $ v; var_export ($ v, true); ...
hanshenrik
3
Przestańcie prześladować ludzi. var_exportnie jest lepsza do debugowania, ponieważ nie można zrobić wyszukiwania przeglądarki, (int)lub (string) `i itd. To również Mangles a lot informacji w małej przestrzeni, po prostu spróbuj: var_export(''); var_export('\'');. A co najważniejsze, przygotuj się na błąd krytyczny PHP: zbyt głęboki poziom zagnieżdżenia - zależność rekurencyjna? w C: \ ścieżka \ plik.php w linii 75
Pacerier
76

Możesz także to zrobić:

$dump = print_r($variable, true);
Ian P.
źródło
17
W szczególności wspomniałem o var_dump :)
Mark Biek
7
Osobiście wolę korzystać z tego, print_rco mogę, ale niestety czasami nie zapewnia wystarczającej ilości informacji. Na przykład, ponieważ rzutuje na ciąg tam, gdzie może, zarówno falsei nullpokazuje się jako pusty ciąg. W przypadkach, w których zależy mi na różnicy między nimi, niechętnie skorzystam z var_dumplub var_export.
JMTyler
15

Możesz także spróbować użyć tej serialize()funkcji. Czasami jest to bardzo przydatne do celów debugowania.

Sergey Stolyarov
źródło
7
Słowo ostrzeżenia - jeśli powód, dla którego chcesz, aby wynik był ciągiem error_log, nie powinieneś używać tego rozwiązania, ponieważ dane wyjściowe serialize mogą zawierać bajty puste i error_log obcinać ciągi zawierające bajty puste .
Mark Amery
15
function return_var_dump(){
    // It works like var_dump, but it returns a string instead of printing it.
    $args = func_get_args(); // For <5.3.0 support ...
    ob_start();
    call_user_func_array('var_dump', $args);
    return ob_get_clean();
}
hanshenrik
źródło
4
@MarkAmery Wydaje się prawdą. Właśnie to ułatwiłem.
hanshenrik
13

Również echo json_encode($dataobject);może być pomocne

ZurabWeb
źródło
1
W tym przypadku dane wyjściowe są moim zdaniem bardzo mylące i dalekie od celu debugowania.
Tomáš Zato - Przywróć Monikę
2
Mark Biek nie mówił nic o debugowaniu, prawda? Może po prostu potrzebuje obiektu zapisanego w bazie danych. W tym przypadku moja zaproponowana metoda działałaby dobrze. W każdym razie dzięki za heads-up, Tomáš Zato.
ZurabWeb
W każdym razie json_encodenie będzie zawierać wszystkich danych var_dump(na przykład typów zmiennych). json_encodewypisuje te same informacje, co print_Rw innym formacie.
Tomáš Zato - Przywróć Monikę
1
Ok, wyjaśnię to jeszcze raz . OT stwierdził, że potrzebuje produkcji var_dump. Stwierdził również, że print_Rzapewnia on niewystarczające informacje dla jego potrzeb. Nie ma prawdziwej różnicy w informacjach dostarczanych przez json_encodei print_r- tylko format danych jest inny. Biorąc to pod uwagę, jeśli print_rjest niewystarczające, tak też jest json_encode. Proszę nie narzekać już na głosowanie negatywne. Oczywiście nie było to zwykłe kliknięcie, więc sobie z tym poradzić.
Tomáš Zato - Przywróć Monikę
9

Z podręcznika PHP :

Ta funkcja wyświetla uporządkowane informacje o jednym lub większej liczbie wyrażeń, które obejmują jego typ i wartość.

Oto prawdziwa zwracana wersja PHP var_dump(), która akceptuje listę argumentów o zmiennej długości:

function var_dump_str()
{
    $argc = func_num_args();
    $argv = func_get_args();

    if ($argc > 0) {
        ob_start();
        call_user_func_array('var_dump', $argv);
        $result = ob_get_contents();
        ob_end_clean();
        return $result;
    }

    return '';
}
Younis Bensalah
źródło
1
+1 za udzielenie prawdziwej odpowiedzi na aktualne pytanie. Czytam to, ponieważ potrzebuję var_dump, a nie var_export, print_r, serialize, json_encode lub prawdziwego debuggera. Wiem też, jak z nich korzystać. OP poprosił o var_dump, potrzebuję var_dump. Dziękuję Ci!
Slashback,
jeśli chcesz pozostać wierny var_dump, musisz trigger_error („Zła liczba parametrów dla var_dump_str ()”); gdy argc <= 0; lub jeszcze lepiej, niech var_dump zrobi to za Ciebie. : p
hanshenrik
Dodaje to prawie nic, co nie było jeszcze w zaakceptowanej odpowiedzi. $argcSprawdzić tutaj jest niepotrzebne i prawdopodobnie błędne jak podkreślił @hanshenrik, a kiedy się stąd, że wszystko tak naprawdę jest dodawanie call_user_func_arrayi func_get_argspołączeń.
Mark Amery
5

Jeśli chcesz rzucić okiem na zawartość zmiennej podczas uruchamiania, rozważ użycie prawdziwego debuggera, takiego jak XDebug. W ten sposób nie musisz zepsuć kodu źródłowego i możesz użyć debugera, nawet gdy normalni użytkownicy odwiedzają Twoją aplikację. Nie zauważą.

selfawaresoup
źródło
5

Oto kompletne rozwiązanie jako funkcja:

function varDumpToString ($var)
{
    ob_start();
    var_dump($var);
    return ob_get_clean();
}
Khandad Niazi
źródło
2
nie będzie działać z więcej niż 1 zmienną ... var_dump („foo”, „bar”) => string (3) „foo” string (3) „bar” varDumpToString („foo”, „bar”) => string (3) „foo”
hanshenrik
2

To może trochę nie na temat.

Szukałem sposobu na zapisanie tego rodzaju informacji w dzienniku Docker mojego kontenera PHP-FPM i wymyśliłem poniższy fragment kodu. Jestem pewien, że mogą to wykorzystać użytkownicy Docker PHP-FPM.

fwrite(fopen('php://stdout', 'w'), var_export($object, true));
Charlie Vieillard
źródło
1
uchwyt nigdy nie jest zamknięty, więc jest to wyciek zasobów, co może stanowić problem w długo działających skryptach w stylu demona. ale spróbujfile_put_contents('php://stdout',var_export($object, true),FILE_APPEND);
hanshenrik
0

Naprawdę podoba mi się var_dump()„S gadatliwy wyjścia i nie był zadowolony z var_export()” s lub print_r()„s wyjścia, ponieważ nie dać jak najwięcej informacji (np typ danych brakuje, długość brakuje).

Aby napisać bezpieczny i przewidywalny kod, czasem warto rozróżnić pusty ciąg znaków od wartości null. Lub od 1 do prawdy. Lub między wartością zerową a fałszywą. Więc chcę mój typ danych w danych wyjściowych.

Chociaż było to pomocne, nie znalazłem prostego i prostego rozwiązania w istniejących odpowiedziach, aby przekonwertować kolorowe dane var_dump()wyjściowe na dane czytelne dla człowieka na ciąg bez tagów HTML i zawierających wszystkie szczegóły var_dump().

Zauważ, że jeśli masz kolor var_dump(), oznacza to, że masz zainstalowany Xdebug, który zastępuje domyślny php var_dump()dodawania kolorów HTML.

Z tego powodu stworzyłem tę niewielką odmianę, podając dokładnie to, czego potrzebuję:

function dbg_var_dump($var)
    {
        ob_start();
        var_dump($var);
        $result = ob_get_clean();
        return strip_tags(strtr($result, ['=&gt;' => '=>']));
    }

Zwraca poniższy ładny ciąg:

array (size=6)
  'functioncall' => string 'add-time-property' (length=17)
  'listingid' => string '57' (length=2)
  'weekday' => string '0' (length=1)
  'starttime' => string '00:00' (length=5)
  'endtime' => string '00:00' (length=5)
  'price' => string '' (length=0)

Mam nadzieję, że to komuś pomoże.

Wadih M.
źródło
-2

Od http://htmlexplorer.com/2015/01/assign-output-var_dump-print_r-php-variable.html :

Funkcje var_dump i print_r mogą wyświetlać dane tylko bezpośrednio w przeglądarce. Tak więc wyjście tych funkcji można odzyskać tylko przy użyciu funkcji kontroli wyjścia php. Poniższa metoda może być przydatna do zapisania wyniku.

function assignVarDumpValueToString($object) {
    ob_start();
    var_dump($object);
    $result = ob_get_clean();
    return $result;
}

ob_get_clean () może wyczyścić tylko ostatnie dane wprowadzone do bufora wewnętrznego. Tak więc metoda ob_get_contents przyda się, jeśli masz wiele wpisów.

Z tego samego źródła, co powyżej:

function varDumpToErrorLog( $var=null ){
    ob_start();                    // start reading the internal buffer
    var_dump( $var);          
    $grabbed_information = ob_get_contents(); // assigning the internal buffer contents to variable
    ob_end_clean();                // clearing the internal buffer.
    error_log( $grabbed_information);        // saving the information to error_log
}
Dev C
źródło
1
Proszę właściwie wskazać, kiedy cytujesz materiał z innego źródła. Przed edycją, którą zamierzam wprowadzić, jedyną częścią tej odpowiedzi sformatowaną jako cytat jest część, której nie skopiowałeś ani nie wkleiłeś z czyjegoś bloga.
Mark Amery
-2

Długi ciąg : użyj echo($var);zamiast dump($var);.

Obiekt lub tablica :var_dump('<pre>'.json_encode($var).'</pre>);'

Vuchkov
źródło