sfaut / insight
Readable var_dump()/print_r() alternative with a colored CLI renderer and a collapsible HTML renderer, configurable truncation, and circular-reference detection.
Requires
- php: ^8.4
- ext-mbstring: *
Requires (Dev)
- pestphp/pest: ^5.1
- phpstan/phpstan: ^2.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-12 19:20:16 UTC
README
A PHP library that inspects a variable and renders a readable representation of it, the way
var_dump() or print_r() do -- with a colored CLI renderer and a collapsible HTML renderer,
both built from the same introspection pass.
PSR-4 root namespace sfaut\Insight\, no dependency on any framework
or application code -- usable as a standalone package.
Why
var_dump() is noisy -- a type name on every scalar, a length on every string,
an object(Class)#N (M) wrapper, ["prop":"Class":private] decorations on
every property -- and gives no way to bound how much of a deep or wide structure gets printed short of writing
your own recursive walker. print_r() is quieter but loses type information and offers the same lack
of control. Neither one gives you HTML output or independent truncation limits for arrays,
strings, and nesting depth.
Insight aims for var_dump()-level detail with print_r()-level readability: bare scalars,
a quoted string with no length suffix, an object's own class name with no object(...) wrapper,
property names as plain quoted strings with only a visibility symbol (+/#/−) -- and,
on top of that, configurable head/tail truncation for arrays (independently for list-shaped,
map-shaped, and sparse arrays), for long strings, for multiline strings, and for nesting depth,
plus circular-reference detection for both objects and arrays.
What it looks like
use sfaut\Insight\Insight; Insight::view([ 'id' => 42, 'name' => 'Widget', 'price' => 19.99, 'tags' => ['new', 'sale'], 'shape' => $circle, ]);
map:5 [
"id" => 42
"name" => "Widget"
"price" => 19.99
"tags" => list:2 [
0 => "new"
1 => "sale"
]
"shape" => Circle:3 {
+"radius" => 2.5
−"color" => "red"
#"count" => 1
}
]
Colored when run in an interactive terminal (auto-detected), plain text when piped or redirected, or a collapsible HTML block when running outside the CLI SAPI -- no configuration needed for either switch.
Requirements
PHP 8.4+. (The library's own code under src/ only uses PHP 8.1-level language features --
enums, readonly properties, array_is_list() -- but the dev tooling, pestphp/pest ^5.1,
requires PHP 8.4+, so that's the honest floor for the published package too.)
Installation
composer require sfaut/insight
Usage
The facade
use sfaut\Insight\Insight; Insight::view($v); // echoes the rendered dump, plus a trailing newline $dump = Insight::render($v); // returns the rendered dump as a string instead Insight::write('/tmp/dump.txt', $v); // writes it to a file
Every method takes the same per-call $options array as its last argument, merged on top of the
current global configuration for that one call only:
Insight::view($v, ['maxDepth' => 2, 'maxListBeginElements' => 5]);
Global configuration
Insight::configure(['colors' => false, 'indentSize' => 2]); Insight::view($v); // now uses 2-space indentation, no color Insight::reset(); // back to the built-in defaults
Truncating a large collection
Arrays are shown as a head + tail preview once they exceed their configured limits, which are
independent for list-shaped (array_is_list()), map-shaped (at least one string key), and sparse
arrays:
Insight::view(range(1, 30), ['maxListBeginElements' => 3, 'maxListEndElements' => 2]);
list:30 [
0 => 1
1 => 2
2 => 3
… (25 more items)
28 => 29
29 => 30
]
Each of the six max{List,Map,Array}{Begin,End}Elements options independently controls one side
of one array shape. null on a given side means that side contributes nothing -- not "no
limit", but "show zero items from there":
maxListBeginElements: null, maxListEndElements: 5-- shows only the last 5 items, nothing from the start.maxListBeginElements: null, maxListEndElements: null-- both sides contribute nothing to truncate against, which is the one case handled as "no truncation at all": the array is always shown in full.- A collection that already fits within
begin + endis also shown in full, with no…gap, regardless of the limits.
Object properties are never truncated by count, and objects are always walked in full regardless
of maxDepth -- only arrays get cut off by depth (rendered as *DEEP*).
Circular references
Both an object referencing itself and an array containing a reference to itself
($a['self'] = &$a;) are detected and rendered as *RECURSION* instead of looping forever:
$node = new Node(); $node->next = $node; Insight::view($node);
Node:1 {
+"next" => *RECURSION*
}
HTML output
Insight::view($v, ['format' => 'html']); // force HTML regardless of PHP_SAPI
format defaults to auto-detecting PHP_SAPI ('cli' on the command line, 'html'
otherwise); colors defaults to auto-detecting whether STDOUT is an interactive TTY.
The main configuration options
| Option | Type | Default | Role |
|---|---|---|---|
maxDepth |
int |
10 |
Nesting levels walked before an array is truncated (*DEEP*); objects are always walked in full. |
maxListBeginElements / maxListEndElements |
int|null |
20 / 20 |
Items kept at the start/end of a list-shaped array. |
maxMapBeginElements / maxMapEndElements |
int|null |
null / null |
Same, for a map-shaped array (at least one string key). |
maxArrayBeginElements / maxArrayEndElements |
int|null |
20 / 20 |
Same, for a sparse/non-zero-based array. |
indentSize |
int |
4 |
Spaces (CLI) or characters (HTML) per indentation level. |
maxStringLength |
int |
100 |
Characters shown for a single-line string before truncation. |
maxStringLines / maxLineLength |
int |
4 / 100 |
Lines shown for a multiline string, and characters shown per line, before truncation. |
colors |
bool|null |
null |
Force ANSI colors on/off in CLI; null auto-detects the TTY. |
format |
string|null |
null |
Force 'cli' or 'html'; null auto-detects from PHP_SAPI. |
maxStringLength and maxLineLength count and cut in UTF-8 characters (mb_strlen()/
mb_substr()), not bytes -- a multi-byte character is never split in half.
See the docblock on sfaut\Insight\Config's constructor for the full, authoritative list.
Limitations
- Circular-reference detection for arrays only covers a reference created directly in the array
(
$a[] = &$a;); a cycle reached through an object property is bounded bymaxDepthinstead (*DEEP*), without an explicit*RECURSION*marker -- reading a property through reflection copies its value and loses the reference. - Class constants and methods are never shown on an object -- only its properties, to keep the dump focused on state rather than definition.
- A
Closureis inspected like any other object; since it exposes no reflectable properties, it always renders asClosure:0 {}. - CLI colors are a single fixed palette -- there is no theme/palette option to customize them.
The HTML renderer's colors are likewise fixed in an embedded stylesheet, adapting to
light/dark via
prefers-color-scheme.
License
MIT -- see LICENSE.