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.

Odpowiedzi:


601

Użyj buforowania wyjściowego:

<?php
ob_start();
var_dump($someVar);
$result = ob_get_clean();
?>

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.


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

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

4
@MarkAmery Wydaje się prawdą. Właśnie to ułatwiłem.
— hanshenrik

13

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


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 '';
}

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żą.


5

Oto kompletne rozwiązanie jako funkcja:

function varDumpToString ($var)
{
    ob_start();
    var_dump($var);
    return ob_get_clean();
}

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

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.


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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.