Sage
☯ Insightful PHP Debugging Assistant. Exceeds expectations. PHP 5.1→8.3
Install / Use
/learn @php-sage/SageREADME
Sage - Insightful PHP debugging assistant ☯
At first glance Sage is just a drop-in replacement for var_dump() and debug_backtrace().
However, it's much, much more.

Sage is designed to exceed expectations, it intelligently handles everything that you throw at it and displays in the best possible way.
If you can think of how it can be better, please create an issue!
For an overview of Sage's outstanding features jump to the F.A.Q.
Installation
composer require php-sage/sage --dev
Or if you prefer, download the phar and simply
<?php
require 'sage.phar';
sage('Hello, 🌎!');
Or if your PHP version does not support either, download the latest source code and include Sage.php
require 'sage-main/Sage.php';
sage('Hello, 🌎!');
Usage
sage($GLOBALS, $_SERVER); // dump any number of parameters
saged($i); // alias for sage();die;
sage(1); // shortcut for dumping trace
| Function | Shorthand | |
|-------------|-----------|--------------------------------------------------|
| sage | s | Dump (same as \Sage::dump()) |
| saged | sd | Dump & die |
| ssage | ss | Simple dump |
| ssaged | ssd | Simple dump & die |
| sagetrace | s(1) | Debug backtrace (same as \Sage::trace()) |
Simple dump:

Debug backtrace:

Guarantees ✅
-
Sage just works and it displays ALL available information (or in cases when something is truncated - that is clear too).
-
Each release is vigorously tested. Or - use the bleeding edge
dev-mainversion at your own risk. -
Semver versioning ensures there's no compatibility breaks if you use it in your production (eg. reporting).
-
Sage has gotten lots of love and improvements in the last >10 years. It is used by a lot of real people in a lot of real-world scenarios, it is battle tested and has a lot of advanced features no other tool has.
More cool stuff
Sage displays the passed variable name and supports prefixes to the dump function call. Use it for some common on-the-fly adjustments to the dump output.
~ss($var); // outputs plain text
$output = @ss($var); // returns output instead of displaying it
! sage($var); // ignores depth limit for large objects
+ sage($var); // auto-expands the view
print sd($var); // saves output into "sage.html" in the current directory
print ! sd($var); // saves output into "sage.html" while also ignoring the output depth limit!
Sage tokenizes & introspects the calling code to get all this information. All that can be done with prefixes can also be achieved with standard, verbose syntax:
~ss($var);
// is equivalent to:
Sage::enabled(Sage::MODE_TEXT_ONLY);
Sage::dump($var);
See Advanced section below if you want more tips & tricks.
Verbose versions
If you want to use Sage as part of permanent code (e.g. part of a test helper/logger/exception reporter etc), you can use the verbose way to invoke Sage:
// instead of sage()
Sage::dump('this looks way less hacky (yeah right:)');
// equivalent to sage(1);
Sage::trace();
// a real-life test helper:
class TestHelper{
public function getVarDump(mixed $providedContext): string
{
if (! $providedContext) {
return '';
}
$state = Sage::saveState();
Sage::enabled(Sage::MODE_TEXT_ONLY);
Sage::$aliases[] = __CLASS__ . '::' . __FUNCTION__;
Sage::$returnOutput = true;
Sage::$displayCalledFrom = false;
$debugOutput = Sage::dump($providedContext);
Sage::saveState($state); // now reset settings to presumed defaults
return PHP_EOL . $debugOutput;
}
}
Customization
The main goal of Sage is to be zero-setup. There are also several customization options for advanced uses.
Where to store the configuration?
- Add this entry to the
autoload.filesconfiguration incomposer.json:
"autoload": {
"files": [
"config/sage.php" /* <--------------- create this file with your settings! */
]
}, ...
- Put settings inside of
php.ini:
; change sage theme:
sage.theme = solarized-dark
; always display all dump levels, almost always crashes the browser:
sage.maxLevels = 0
; set your IDE links
sage.editor = vscode
; disable Sage unless explicitly enabled
sage.enabled = 0
- Include the desired settings in your bootstrap process anywhere™.
require 'sage.phar';
Sage::$theme = Sage::THEME_LIGHT;
All available options
Sage::$theme = Sage::THEME_ORIGINAL;
Currently available themes are:
Sage::THEME_ORIGINALSage::THEME_LIGHTSage::THEME_SOLARIZEDSage::THEME_SOLARIZED_DARK
Sage::$editor = ini_get('xdebug.file_link_format');
Make visible source file paths clickable to open your editor. Available options are:
'phpstorm-remote'- default (requires IDE Remote Control plugin),'sublime','textmate','emacs','macvim','phpstorm','idea','vscode','vscode-insiders','vscode-remote','vscode-insiders-remote','vscodium','atom','nova','netbeans','xdebug'
Or pass a custom string where %file should be replaced with full file path, %line with line number to create a custom link. Set to null to disable linking.
Sage::$displayCalledFrom = true;
Whether to display where Sage was called from
Sage::$maxLevels = 7;
Max array/object levels to go deep, set to zero/false to disable
Sage::$expandedByDefault = false;
Draw rich output already expanded without having to click
Sage::$cliDetection = true;
Enable detection when running in command line and adjust output format accordingly.
Sage::$cliColors = true;
In addition to above setting, enable detection when Sage is run in UNIX command line. Attempts to add coloring, but if opened as plain text, the color information is visible as gibberish.
Sage::$charEncodings = [ 'UTF-8', 'Windows-1252', 'euc-jp' ]
Possible alternative char encodings in order of probability.
Sage::$returnOutput = false;
Sage returns output instead of printing it.
Sage::$aliases;
Add new custom Sage wrapper names. Optional, but needed for backtraces, variable name detection and modifiers to work
properly. Accepts array or comma separated string. Use notation Class::method for methods.
🧙 Advanced Tips & Tricks
this section is under construction :)
// we already saw:
sage($GLOBALS, $_SERVER);
// you can also go shorter for the same result:
s($GLOBALS, $_SERVER);
// or you can go the verbose way, it's all equivalent:
Sage::dump($GLOBALS, $_SERVER);
// ss() will display a more basic, javascript-free display (but with colors)
ss($GLOBALS, $_SERVER);
// to recap: s() or sage() - dumps. Add "d" to die afterwards: sd(), saged()
// preppend "s" to simplify output: ss(), ssage().
// works in combination, too: ssd() and ssagedd() will dump in "simple mode" and die!
// prepending a tilde will make the output *even more basic* (rich->basic and basic->plain text)
~d($GLOBALS, $_SERVER); // more on modifiers below
// show a trace
Sage::trace();
s(1); // shorthand works too!
s(2); // trace - but just the paths
Sage::dump( debug_backtrace() ); // you can even pass a custom result from debug_trace and it will be recognized
// dump and die debugging
sd($GLOBALS, $_SERVER); // dd() might be taken by your framework
saged($GLOBALS, $_SERVER); // so this is an equivalent alternative
ssd($GLOBALS, $_SERVER); // available for plain display too!
// this will disable Sage completely
Sage::enabled(false);
sd('Get off my lawn!'); // no effect
-
Sage supports keyboard shortcuts! Just press <kbd>d</kbd> when viewing output and the rest is self-explanatory, try it out! (p.s. vim-style
hjklworks as well); -
Call
Sage::enabled(Sage::MODE_PLAIN);to switch to a simpler, js-free output. -
Call
Sage::enabled(Sage::MODE_TEXT_ONLY);for pure-plain text output which you can save or pass around by first settingSage::$returnOutput = true; -
Sage can provide a plain-text version of its output and does so automatically when invoked via PHP running in command line mode.

-
Double clicking the
[+]sign in the output will expand/collapse ALL nodes; triple clicking a big block of text will select it all. -
Clicking the tiny arrow on the right of the output will open it in a separate window where you can keep it for comparison.
-
Sage supports themes:

For customization instructions read the section below.
-
If a variable is an object, its classname can be clicked to open the class in your IDE.
-
There are several real-time prefix modifiers you can use (combinations possible):
| Prefix | | Example | |--------|----------------------------------------------|--------------| | print | Puts output into current DIR as sage.html | print sage() | | ! | Dump ignoring depth limits for large objects | ! sage() | | ~ | Simplifies sage output (rich->html->plain) | ~ sage()
Related Skills
node-connect
340.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
340.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.2kCommit, push, and open a PR
