Kint

Zero-setup replacement for var_dump().

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)
      • usernamecreatedlastlog
        0monkey2017-01-25 22:24:082017-01-28 14:49:51
        1tiger2017-01-03 11:40:502017-01-09 17:44:48
        2mantis2017-01-03 12:19:482017-01-10 14:46:51
        3snake2017-01-11 22:15:252017-02-06 01:45:46
        4crane2017-01-09 22:28:342017-01-22 00:12:26
        5panda2017-01-14 13:20:402017-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)
Called from /demo.php:9 [d()]

Let’s take a look at this data with Kint

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 to ob_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

Advanced usage »