Types7 min readExamples run on PHP 8.5.10

var_dump()

Learn how PHP's var_dump() prints the type, size and value of expressions, including arrays and objects, and where it misleads you.

Signature

var_dump(mixed $value, mixed ...$values): void

Purpose

var_dump() prints structured debugging information about one or more expressions. For every value it shows the type, and for most types also the size and the value. Arrays and objects are walked recursively, and indentation shows how they are nested. It is the quickest way to answer "what exactly is in this variable?", especially when echo hides the difference between 1, "1", true and 1.0.

The output is meant for developers, not for users or other programs. If you need text you can parse back into PHP, look at var_export() or json_encode() instead.

Signature

Parameters and defaults

  • $value: the expression to dump. It is required, so calling var_dump() with no arguments throws an ArgumentCountError.
  • ...$values: any number of further expressions. Each one is dumped in order, one after another.

There are no optional settings. You cannot choose the indentation, the depth or the output format.

Return value and failure cases

The function returns void. The result is written straight to the output, so you cannot assign it to a variable. To capture the text, wrap the call in output buffering with ob_start() and ob_get_clean().

The function has no failure return value. Any value can be dumped, and an unusual value such as a recursive array is marked in the output rather than causing an error.

Example 1: scalars and multiple arguments

Passing several arguments dumps each one on its own. Strings report their length in bytes, not characters, and floats show the precision PHP actually stores.

Example
<?php
var_dump(42, "42", 0.1 + 0.2, "héllo", null);
Output
int(42)
string(2) "42"
float(0.30000000000000004)
string(6) "héllo"
NULL

The integer and the numeric string are clearly different. The accented string reports 6 bytes because é takes two bytes in UTF-8. The float sum reveals the usual binary rounding.

Example 2: nested arrays

Keys are shown in brackets, and string keys are quoted. The number in parentheses after array is the count of elements at that level.

Example
<?php
$data = ["id" => 7, "tags" => ["php", "dump"], "active" => false];
var_dump($data);
Output
array(3) {
  ["id"]=>
  int(7)
  ["tags"]=>
  array(2) {
    [0]=>
    string(3) "php"
    [1]=>
    string(4) "dump"
  }
  ["active"]=>
  bool(false)
}

The nested tags array is indented one level deeper, with its own element count.

Example 3: objects and visibility

For objects, var_dump() shows the class name, an object handle number after #, the property count, and each property. Private and protected properties are included and annotated with their visibility.

Example
<?php
class Point
{
    public function __construct(
        public int $x,
        private int $y,
    ) {}
}

var_dump(new Point(1, 2));
Output
object(Point)#1 (2) {
  ["x"]=>
  int(1)
  ["y":"Point":private]=>
  int(2)
}

The #1 is the identifier of the object instance. It depends on how many objects are currently alive, so do not treat it as a stable value.

Edge cases

  • Floats: 1.0 prints as float(1), and special values print as float(NAN) and float(INF). Negative zero prints as float(-0).
  • Uninitialized typed properties: they are listed with an uninitialized(type) marker instead of a value.
  • Recursion: a structure that contains itself is cut off with *RECURSION* instead of looping forever.
  • Custom output: if a class implements __debugInfo(), var_dump() shows the array returned by that method rather than the real properties. This can hide data, so remember it when the output looks incomplete.
  • Enums and closures: enum cases are printed with the enum name and case, and closures appear as objects of the Closure class.
  • Extensions: a debugging extension such as Xdebug may replace the default format, so the output on your machine can differ from the plain format shown here.

Common mistakes

  1. Leaving it in production code. Debug output can leak private properties, passwords and internal structure. Remove it or send it to a log through output buffering.
  2. Expecting a return value. $text = var_dump($x); gives null. Capture with ob_start() and ob_get_clean() instead.
  3. Reading string length as character count. The number is bytes. Use mb_strlen() when you need characters.
  4. Comparing dumped output in tests. Object handle numbers and extension formatting can change, so assert on values directly.
  5. Using it for HTML pages. The plain-text format collapses whitespace in a browser. Wrapping the output in <pre> is a common workaround, but a debugger or logging is a better habit.
  • print_r() prints a more compact human-readable form without types.
  • var_export() prints or returns valid PHP code that represents the value.
  • debug_zval_dump() also shows internal reference-count details.
  • __debugInfo() lets a class control what var_dump() reveals.

Recap

var_dump() accepts one or more expressions, prints each type and value (recursing into arrays and objects), and returns nothing. Use it to see exact types and hidden details, remember that string sizes are in bytes, and never rely on its output as a data format.

Tested examples

Scalars and multiple arguments
<?php
var_dump(42, "42", 0.1 + 0.2, "héllo", null);
Output
int(42)
string(2) "42"
float(0.30000000000000004)
string(6) "héllo"
NULL
Nested arrays
<?php
$data = ["id" => 7, "tags" => ["php", "dump"], "active" => false];
var_dump($data);
Output
array(3) {
  ["id"]=>
  int(7)
  ["tags"]=>
  array(2) {
    [0]=>
    string(3) "php"
    [1]=>
    string(4) "dump"
  }
  ["active"]=>
  bool(false)
}
Objects and property visibility
<?php
class Point
{
    public function __construct(
        public int $x,
        private int $y,
    ) {}
}

var_dump(new Point(1, 2));
Output
object(Point)#1 (2) {
  ["x"]=>
  int(1)
  ["y":"Point":private]=>
  int(2)
}