Kint - Advanced PHP dumper
What is it?
Kint is a dumper in the vein of var_dump
, with keyboard controls, search, access path provision, and automatic data parsing.
Install with composer
composer require kint-php/kint
Install a phar file
Basic usage
Live demo
You have some data and you need to get more data out of it, but you don’t know how the data is structured until you poke around inside it.
This output was pre-recorded
',this.#s=e.content.firstChild,t.body.appendChild(this.#s)}}get folder(){return d(this.#s)||(this.#s=this.#e.window.document.querySelector(".kint-rich.kint-folder")),this.#s&&m(this.#s),this.#s}isFolderOpen(){let t=this.#s?.querySelector("dd.kint-foldout");if(t)return t.previousSibling.classList.contains("kint-show")}static getChildContainer(t){let e=t.nextElementSibling;for(;e&&!e.matches("dd");)e=e.nextElementSibling;return e}static toggle(t,e){let s=n.getChildContainer(t);s&&(e=t.classList.toggle("kint-show",e),n.#n(s,e))}static switchTab(t){t.parentNode.getElementsByClassName("kint-active-tab")[0].classList.remove("kint-active-tab"),t.classList.add("kint-active-tab");let e=t,s=0;for(;e=e.previousElementSibling;)s++;let i=t.parentNode.nextSibling.children;for(let r=i.length;r--;)r===s?(i[r].classList.add("kint-show"),n.#n(i[r],!0)):i[r].classList.remove("kint-show")}static toggleChildren(t,e){let s=n.getChildContainer(t);if(!s)return;e===void 0&&(e=t.classList.contains("kint-show"));let i=Array.from(s.getElementsByClassName("kint-parent"));for(let r of i)r.classList.toggle("kint-show",e)}static toggleAccessPath(t,e){let s=t.querySelector(".access-path");s?.classList.toggle("kint-show",e)&&f(s)}static#n(t,e){if(t.children.length===2&&t.lastElementChild.matches("ul.kint-tab-contents"))for(let s of t.lastElementChild.children)s.matches("li.kint-show")&&(t=s);if(t.children.length===1&&t.firstElementChild.matches("dl")){let s=t.firstElementChild.firstElementChild;s?.classList?.contains("kint-parent")&&n.toggle(s,e)}}},b=class{#e;#t;#s;#i=null;#n=null;#o=0;constructor(t,e,s){this.#e=t,this.#t=s,this.#s=e,this.#s.addEventListener("click",this.#a.bind(this),!0)}#r(){clearTimeout(this.#i),this.#i=setTimeout(this.#l.bind(this),250)}#l(){clearTimeout(this.#i),this.#i=null,this.#n=null,this.#o=0}#c(){let t=this.#n;if(!t.matches(".kint-parent > nav"))return;let e=t.parentNode;if(this.#o===1)a.toggleChildren(e),this.#t.onTreeChanged(),this.#r(),this.#o=2;else if(this.#o===2){this.#l();let s=e.classList.contains("kint-show"),i=this.#e.folder?.querySelector(".kint-parent"),r=Array.from(this.#s.document.getElementsByClassName("kint-parent"));for(let o of r)o!==i&&o.classList.toggle("kint-show",s);this.#t.onTreeChanged(),this.#t.scrollToFocus()}}#a(t){if(this.#o){this.#c();return}let e=t.target;if(!e.closest(".kint-rich"))return;if(e.tagName==="DFN"&&f(e),e.tagName==="TH"){t.ctrlKey||g.sort(e.closest("table"),e.cellIndex);return}if(e.tagName==="LI"&&e.parentNode.className==="kint-tabs"){if(e.className!=="kint-active-tab"){let i=e.closest("dl")?.querySelector(".kint-parent > nav")??e;a.switchTab(e),this.#t.onTreeChanged(),this.#t.setCursor(i)}return}let s=e.closest("dt");if(e.tagName==="NAV")e.parentNode.tagName==="FOOTER"?(this.#t.setCursor(e),e.parentNode.classList.toggle("kint-show")):s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(e),this.#r(),this.#o=1,this.#n=e);else if(e.classList.contains("kint-access-path-trigger"))s&&a.toggleAccessPath(s);else if(e.classList.contains("kint-search-trigger"))s?.matches(".kint-rich > dl > dt.kint-parent")&&u.toggleSearchBox(s);else if(e.classList.contains("kint-folder-trigger")){if(s?.matches(".kint-rich > dl > dt.kint-parent"))this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav")),this.#t.scrollToFocus();else if(e.parentNode.tagName==="FOOTER"){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#e.addToFolder(e),this.#t.onTreeChanged(),this.#t.setCursor(i),this.#t.scrollToFocus()}}else e.classList.contains("kint-search")||(e.tagName==="PRE"&&t.detail===3?f(e):e.closest(".kint-source")&&t.detail===3?f(e.closest(".kint-source")):e.classList.contains("access-path")?f(e):e.tagName!=="A"&&s?.classList.contains("kint-parent")&&(a.toggle(s),this.#t.onTreeChanged(),this.#t.setCursor(s.querySelector("nav"))))}},j=65,G=68,A=70,S=72,K=74,D=75,p=76,V=83,P=9,T=13,B=27,L=32,N=37,R=38,C=39,H=40,M=".kint-rich .kint-parent > nav, .kint-rich > footer > nav, .kint-rich .kint-tabs > li:not(.kint-active-tab)",q=class{#e=[];#t=0;#s=!1;#i;#n;constructor(t,e){this.#i=t,this.#n=e.window,this.#n.addEventListener("keydown",this.#c.bind(this),!0),e.runOnInit(this.onTreeChanged.bind(this))}scrollToFocus(){let t=this.#e[this.#t];if(!t)return;let e=this.#i.folder;if(t===e?.querySelector(".kint-parent > nav"))return;let s=x(t);if(this.#i.isFolderOpen()){let i=e.querySelector("dd.kint-foldout");i.scrollTo(0,s-i.clientHeight/2)}else this.#n.scrollTo(0,s-this.#n.innerHeight/2)}onTreeChanged(){let t=this.#e[this.#t];this.#e=[];let e=this.#i.folder,s=e?.querySelector(".kint-parent > nav"),i=this.#n.document;this.#i.isFolderOpen()&&(i=e,this.#e.push(s));let r=Array.from(i.querySelectorAll(M));for(let o of r)o.offsetParent!==null&&o!==s&&this.#e.push(o);if(s&&!this.#i.isFolderOpen()&&this.#e.push(s),this.#e.length===0){this.#s=!1,this.#r();return}t&&this.#e.indexOf(t)!==-1?this.#t=this.#e.indexOf(t):this.#r()}setCursor(t){if(this.#i.isFolderOpen()&&!this.#i.folder.contains(t)||!t.matches(M))return!1;let e=this.#e.indexOf(t);if(e===-1&&(this.onTreeChanged(),e=this.#e.indexOf(t)),e!==-1){if(e!==this.#t)return this.#t=e,this.#r(),!0;this.#e[e]?.classList.remove("kint-weak-focus")}else console.error("setCursor failed to find target in list",t),console.info("Please report this as a bug in Kint at https://github.com/kint-php/kint");return!1}#o(t){if(this.#e.length===0)return this.#t=0,null;for(this.#t+=t;this.#t<0;)this.#t+=this.#e.length;for(;this.#t>=this.#e.length;)this.#t-=this.#e.length;return this.#r(),this.#t}#r(){let t=this.#n.document.querySelector(".kint-focused");t&&(t.classList.remove("kint-focused"),t.classList.remove("kint-weak-focus")),this.#s&&this.#e[this.#t]?.classList.add("kint-focused")}#l(t){let e=t.closest(".kint-rich .kint-parent ~ dd")?.parentNode.querySelector(".kint-parent > nav");e&&(this.setCursor(e),this.scrollToFocus())}#c(t){if(t.keyCode===B&&t.target.matches(".kint-search")){t.target.blur(),this.#s&&this.#r();return}if(t.target!==this.#n.document.body||t.altKey||t.ctrlKey)return;if(t.keyCode===G){if(this.#s)this.#s=!1;else{if(this.#s=!0,this.onTreeChanged(),this.#e.length===0){this.#s=!1;return}this.scrollToFocus()}this.#r(),t.preventDefault();return}else if(t.keyCode===B){this.#s&&(this.#s=!1,this.#r(),t.preventDefault());return}else if(!this.#s)return;t.preventDefault(),d(this.#e[this.#t])||this.onTreeChanged();let e=this.#e[this.#t];if([P,R,D,H,K].includes(t.keyCode)){t.keyCode===P?this.#o(t.shiftKey?-1:1):t.keyCode===R||t.keyCode===D?this.#o(-1):(t.keyCode===H||t.keyCode===K)&&this.#o(1),this.scrollToFocus();return}if(e.tagName==="LI"&&[L,T,C,p,N,S].includes(t.keyCode)){t.keyCode===L||t.keyCode===T?(a.switchTab(e),this.onTreeChanged()):t.keyCode===C||t.keyCode===p?this.#o(1):(t.keyCode===N||t.keyCode===S)&&this.#o(-1),this.scrollToFocus();return}if(e.parentNode.tagName==="FOOTER"&&e.closest(".kint-rich")){if(t.keyCode===L||t.keyCode===T)e.parentNode.classList.toggle("kint-show");else if(t.keyCode===N||t.keyCode===S)if(e.parentNode.classList.contains("kint-show"))e.parentNode.classList.remove("kint-show");else{this.#l(e.closest(".kint-rich"));return}else if(t.keyCode===C||t.keyCode===p)e.parentNode.classList.add("kint-show");else if(t.keyCode===A&&!this.#i.isFolderOpen()&&e.matches(".kint-rich > footer > nav")){let i=e.closest(".kint-rich").querySelector(".kint-parent > nav, .kint-rich > footer > nav");this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(i),this.scrollToFocus()}return}let s=e.closest(".kint-parent");if(s){if(t.keyCode===j){a.toggleAccessPath(s);return}if(t.keyCode===A){!this.#i.isFolderOpen()&&s.matches(".kint-rich:not(.kint-folder) > dl > .kint-parent")&&(this.#i.addToFolder(e),this.onTreeChanged(),this.setCursor(e),this.scrollToFocus());return}if(t.keyCode===V){let i=s.closest(".kint-rich > dl")?.querySelector(".kint-search")?.closest(".kint-parent");if(i){e.classList.add("kint-weak-focus"),u.toggleSearchBox(i,!0);return}}if(t.keyCode===L||t.keyCode===T){a.toggle(s),this.onTreeChanged();return}if([C,p,N,S].includes(t.keyCode)){let i=s.classList.contains("kint-show");if(t.keyCode===C||t.keyCode===p){i&&a.toggleChildren(s,!0),a.toggle(s,!0),this.onTreeChanged();return}else if(i){a.toggleChildren(s,!1),a.toggle(s,!1),this.onTreeChanged();return}else{this.#l(s);return}}}}};var y=class{#e;#t;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Plain.constructor()");this.#e=t.window,t.runOnInit(this.#s.bind(this))}#s(){d(this.#t)||(this.#t=this.#e.document.querySelector("style.kint-plain-style")),this.#t&&m(this.#t)}};var w=class{#e;constructor(t){if(!(t instanceof h))throw new Error("Invalid argument to Microtime.constructor()");this.#e=t.window,t.runOnInit(this.#t.bind(this))}#t(){let t={},e=this.#e.document.querySelectorAll("[data-kint-microtime-group]");for(let s of e){let i=s.querySelector(".kint-microtime-lap");if(!i)continue;let r=s.dataset.kintMicrotimeGroup,o=parseFloat(i.textContent),l=parseFloat(s.querySelector(".kint-microtime-avg").textContent);t[r]??={min:o,max:o,avg:l},t[r].min>o&&(t[r].min=o),t[r].maxo.avg){let l=(r-o.avg)/(o.max-o.avg);i.style.background="hsl("+(40-40*l)+", 100%, 65%)"}else{let l=0;o.avg!==o.min&&(l=(o.avg-r)/(o.avg-o.min)),i.style.background="hsl("+(40+80*l)+", 100%, 65%)"}}}};var U=Symbol(),h=class n{static#e=null;#t;#s=[];#i=new Set;static init(t){return n.#e??=new n(t,U),n.#e.#n(),n.#e.runOnLoad(n.#r),n.#e}get window(){return this.#t}constructor(t,e){if(U!==e)throw new Error("Kint constructor is private. Use Kint.init()");if(!(t instanceof Window))throw new Error("Invalid argument to Kint.init()");this.#t=t,this.runOnInit(this.#o.bind(this)),new y(this),new a(this),new w(this)}runOnLoad(t){if(this.#t.document.readyState==="complete")try{t()}catch{}else this.#t.addEventListener("load",t)}runOnInit(t){this.#s.push(t)}#n(){this.#t.document.currentScript&&(this.#i.add(E(window.document.currentScript)),window.document.currentScript.remove())}#o(){for(let t of this.#i.keys())for(let e of this.#t.document.querySelectorAll(t))e.remove()}static#r(){for(let t of n.#e.#s)t()}};window.Kint||(window.Kint=h);window.Kint.init(window);})();
- $time integer 1486849709
2017-02-11T21:48:29+00:00
- $data string (740) "eyJjb2xvciI6InJnYmEoMjU1LCAyNTUsIDAsIDAuNSkiLCJkYXRhIjpbeyJ1c2VybmFtZSI6Im1v...
- Base64
- Contents
- base64_decode($data) string (555) "{"color":"rgba(255, 255, 0, 0.5)","data":[{"username":"monkey","created":"20...
base64_decode($data)
- Json (2)
- Contents
- color => string (22) "rgba(255, 255, 0, 0.5)"
json_decode(base64_decode($data), true)['color'] yellow #FF0 #FFFF00 #FFFF0080 rgba(255, 255, 0, 0.5) hsla(60, 100%, 50%, 0.5)
- data => array (6)
json_decode(base64_decode($data), true)['data']
- Table (6)
- Contents (6)
username created lastlog 0 monkey 2017-01-25 22:24:08 2017-01-28 14:49:51 1 tiger 2017-01-03 11:40:50 2017-01-09 17:44:48 2 mantis 2017-01-03 12:19:48 2017-01-10 14:46:51 3 snake 2017-01-11 22:15:25 2017-02-06 01:45:46 4 crane 2017-01-09 22:28:34 2017-01-22 00:12:26 5 panda 2017-01-14 13:20:40 2017-01-27 23:14:40
- 0 => array (3)
json_decode(base64_decode($data), true)['data'][0]
- username => string (6) "monkey"
json_decode(base64_decode($data), true)['data'][0]['username']
- created => string (19) "2017-01-25 22:24:08"
json_decode(base64_decode($data), true)['data'][0]['created']
- lastlog => string (19) "2017-01-28 14:49:51"
json_decode(base64_decode($data), true)['data'][0]['lastlog']
- 1 => array (3)
json_decode(base64_decode($data), true)['data'][1]
- username => string (5) "tiger"
json_decode(base64_decode($data), true)['data'][1]['username']
- created => string (19) "2017-01-03 11:40:50"
json_decode(base64_decode($data), true)['data'][1]['created']
- lastlog => string (19) "2017-01-09 17:44:48"
json_decode(base64_decode($data), true)['data'][1]['lastlog']
- 2 => array (3)
json_decode(base64_decode($data), true)['data'][2]
- username => string (6) "mantis"
json_decode(base64_decode($data), true)['data'][2]['username']
- created => string (19) "2017-01-03 12:19:48"
json_decode(base64_decode($data), true)['data'][2]['created']
- lastlog => string (19) "2017-01-10 14:46:51"
json_decode(base64_decode($data), true)['data'][2]['lastlog']
- 3 => array (3)
json_decode(base64_decode($data), true)['data'][3]
- username => string (5) "snake"
json_decode(base64_decode($data), true)['data'][3]['username']
- created => string (19) "2017-01-11 22:15:25"
json_decode(base64_decode($data), true)['data'][3]['created']
- lastlog => string (19) "2017-02-06 01:45:46"
json_decode(base64_decode($data), true)['data'][3]['lastlog']
- 4 => array (3)
json_decode(base64_decode($data), true)['data'][4]
- username => string (5) "crane"
json_decode(base64_decode($data), true)['data'][4]['username']
- created => string (19) "2017-01-09 22:28:34"
json_decode(base64_decode($data), true)['data'][4]['created']
- lastlog => string (19) "2017-01-22 00:12:26"
json_decode(base64_decode($data), true)['data'][4]['lastlog']
- 5 => array (3)
json_decode(base64_decode($data), true)['data'][5]
- username => string (5) "panda"
json_decode(base64_decode($data), true)['data'][5]['username']
- created => string (19) "2017-01-14 13:20:40"
json_decode(base64_decode($data), true)['data'][5]['created']
- lastlog => string (19) "2017-01-27 23:14:40"
json_decode(base64_decode($data), true)['data'][5]['lastlog'] {"color":"rgba(255, 255, 0, 0.5)","data":[{"username":"monkey","created":"2017-01-25 22:24:08","lastlog":"2017-01-28 14:49:51"},{"username":"tiger","created":"2017-01-03 11:40:50","lastlog":"2017-01-09 17:44:48"},{"username":"mantis","created":"2017-01-03 12:19:48","lastlog":"2017-01-10 14:46:51"},{"username":"snake","created":"2017-01-11 22:15:25","lastlog":"2017-02-06 01:45:46"},{"username":"crane","created":"2017-01-09 22:28:34","lastlog":"2017-01-22 00:12:26"},{"username":"panda","created":"2017-01-14 13:20:40","lastlog":"2017-01-27 23:14:40"}]} eyJjb2xvciI6InJnYmEoMjU1LCAyNTUsIDAsIDAuNSkiLCJkYXRhIjpbeyJ1c2VybmFtZSI6Im1vbmtleSIsImNyZWF0ZWQiOiIyMDE3LTAxLTI1IDIyOjI0OjA4IiwibGFzdGxvZyI6IjIwMTctMDEtMjggMTQ6NDk6NTEifSx7InVzZXJuYW1lIjoidGlnZXIiLCJjcmVhdGVkIjoiMjAxNy0wMS0wMyAxMTo0MDo1MCIsImxhc3Rsb2ciOiIyMDE3LTAxLTA5IDE3OjQ0OjQ4In0seyJ1c2VybmFtZSI6Im1hbnRpcyIsImNyZWF0ZWQiOiIyMDE3LTAxLTAzIDEyOjE5OjQ4IiwibGFzdGxvZyI6IjIwMTctMDEtMTAgMTQ6NDY6NTEifSx7InVzZXJuYW1lIjoic25ha2UiLCJjcmVhdGVkIjoiMjAxNy0wMS0xMSAyMjoxNToyNSIsImxhc3Rsb2ciOiIyMDE3LTAyLTA2IDAxOjQ1OjQ2In0seyJ1c2VybmFtZSI6ImNyYW5lIiwiY3JlYXRlZCI6IjIwMTctMDEtMDkgMjI6Mjg6MzQiLCJsYXN0bG9nIjoiMjAxNy0wMS0yMiAwMDoxMjoyNiJ9LHsidXNlcm5hbWUiOiJwYW5kYSIsImNyZWF0ZWQiOiIyMDE3LTAxLTE0IDEzOjIwOjQwIiwibGFzdGxvZyI6IjIwMTctMDEtMjcgMjM6MTQ6NDAifV19
- $object MysteriousObject#2 (2)
- Properties (2)
- Methods (1)
- Static properties (1)
- public definition -> string (143) "
Mysterio... $object->definition
- XML
- Contents
- Mystery SimpleXMLElement (2)
simplexml_load_string($object->definition)
- Children (2)
- Attributes (1)
- Name -> SimpleXMLElement (8) "Mysterio"
simplexml_load_string($object->definition)->Name
- (string) Name string (8) "Mysterio"
(string) simplexml_load_string($object->definition)->Name
- Value -> SimpleXMLElement (6) "Object"
simplexml_load_string($object->definition)->Value
- toString
- Attributes (1)
- (string) Value string (6) "Object"
(string) simplexml_load_string($object->definition)->Value
- type => string (10) "mysterious"
(string) simplexml_load_string($object->definition)->Value['type']
- created => string (19) "2022-11-10 22:33:28"
(string) simplexml_load_string($object->definition)['created']Mysterio Object
- protected created -> DateTime#5 2022-11-10 22:33:28 +00:00 UTC
- Methods (19)
- Static methods (6)
- Class constants (14)
- public __serialize(): array
- public __unserialize(array $data): void
- public __wakeup()
- public format(string $format)
- public modify(string $modifier)
- public add(DateInterval $interval)
- public sub(DateInterval $interval)
- public getTimezone()
- public getOffset()
- public getMicrosecond(): int
- public setTimestamp(int $timestamp)
- public setMicrosecond(int $microsecond): static
- public getTimestamp()
- public static DateTime::__set_state(array $array)
- public static DateTime::createFromImmutable(DateTimeImmutable $object)
- public static DateTime::createFromInterface(DateTimeInterface $object): DateTime
- public static DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null)
- public static DateTime::createFromTimestamp(int|float $timestamp)
- public static DateTime::getLastErrors()
- public const DateTimeInterface::ATOM :: string (13) "Y-m-d\TH:i:sP"
- public const DateTimeInterface::COOKIE :: string (16) "l, d-M-Y H:i:s T"
- public const DateTimeInterface::ISO8601 :: string (13) "Y-m-d\TH:i:sO"
- public const DateTimeInterface::ISO8601_EXPANDED :: string (13) "X-m-d\TH:i:sP"
- public const DateTimeInterface::RFC822 :: string (16) "D, d M y H:i:s O"
- public const DateTimeInterface::RFC850 :: string (16) "l, d-M-y H:i:s T"
- public const DateTimeInterface::RFC1036 :: string (16) "D, d M y H:i:s O"
- public const DateTimeInterface::RFC1123 :: string (16) "D, d M Y H:i:s O"
- public const DateTimeInterface::RFC7231 :: string (21) "D, d M Y H:i:s \G\M\T"
- public const DateTimeInterface::RFC2822 :: string (16) "D, d M Y H:i:s O"
- public const DateTimeInterface::RFC3339 :: string (13) "Y-m-d\TH:i:sP"
- public const DateTimeInterface::RFC3339_EXTENDED :: string (15) "Y-m-d\TH:i:s.vP"
- public const DateTimeInterface::RSS :: string (16) "D, d M Y H:i:s O"
- public const DateTimeInterface::W3C :: string (13) "Y-m-d\TH:i:sP"
- public define(string $definition): void
$object->define() Defined in/demoload.php:58
- private static MysteriousObject::$loaded :: boolean true
Let’s take a look at this data with Kint
- Click anywhere on the bar to unfold it
- Double click
+
to unfold all children - Press
d
to toggle keyboard navigation. - Press
a
or the “⇄” icon on the right to see the access path to get at a piece of data. - Press
s
or the “⌕” icon on the right to open a live search. - Press
f
or the “↧” icon on the right to move the dump to a docked folder. - Change tabs to see different views of data.
-
You can sort tables of data by clicking on the headers.
- Kint automatically detects, unpacks, and parses common formats like XML, base64, and JSON
- Detects common patterns like colors, filenames, tables, and timestamps and displays extra information about them
- Provides the user with the exact piece of code they need to access some information nested deep in the hierarchy
Tips & Tricks
- You can set
Kint::$enabled_mode = false;
to turn off output (For example, in production) - You can set nonces for CSP environments:
Kint\Renderer\AbstractRenderer::$js_nonce
Kint\Renderer\AbstractRenderer::$css_nonce
- There are a couple of real-time modifiers you can use:
+d($var)
will disregard depth level limits and output everything
Careful, this can hang your browser on extremely large objects!!d($var)
will expand the output automatically~d($var)
this call will output in plain text format-d($var)
will attempt toob_clean
the previous output and flush after printing
- Add heavy classes to the blacklist to improve performance:
Kint\Parser\BlacklistPlugin::$shallow_blacklist[] = SomeLargeClass::class;
- To change display theme, use
Kint\Renderer\RichRenderer::$theme = 'theme.css';
. You can pass the absolute path to a CSS file, or use one of the built in themes:original.css
(default)solarized.css
solarized-dark.css
aante-light.css
aante-dark.css
- You can install kint-helpers for more shortcuts and kint-twig for twig integration