/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { if (is_object($variable) || is_array($variable) || (string) $variable !== $variable || !isset($variable[0]) || $variable[0] !== '{' && $variable[0] !== '[' || ($json = json_decode($variable, true)) === null) { return false; } $val = (array) $json; if (empty($val)) { return false; } $this->value = KintParser::factory($val)->extendedValue; $this->type = 'JSON'; return true; }
/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { if (!is_object($variable) || !$variable instanceof \Traversable || stripos(get_class($variable), 'zend') !== false) { return false; } $arrayCopy = iterator_to_array($variable, true); if ($arrayCopy === false) { return false; } $this->value = KintParser::factory($arrayCopy)->extendedValue; $this->type = 'Iterator contents'; $this->size = count($arrayCopy); return true; }
/** * @param $traceData * * @return string */ public static function decorateTrace($traceData) { foreach ($traceData as &$frame) { if (isset($frame['args'])) { KintParser::reset(); $frame['args'] = self::_unparse(KintParser::factory($frame['args'])); } if (isset($frame['object'])) { KintParser::reset(); $frame['object'] = self::_unparse(KintParser::factory($frame['object'])); } } return 'kintDump.push(' . json_encode($traceData) . ');' . 'console.log(kintDump[kintDump.length-1]);'; }
/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { if (!is_object($variable) || !$variable instanceof \SplObjectStorage) { return false; } /** @var $variable \SplObjectStorage */ $count = $variable->count(); if ($count === 0) { return false; } $variable->rewind(); while ($variable->valid()) { $current = $variable->current(); $this->value[] = KintParser::factory($current); $variable->next(); } $this->type = 'Storage contents'; $this->size = $count; return true; }
/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { try { if ((string) $variable === $variable && 0 === strpos($variable, '<?xml')) { $e = libxml_use_internal_errors(true); $xml = simplexml_load_string($variable); libxml_use_internal_errors($e); if (empty($xml)) { return false; } } else { return false; } } catch (\Exception $e) { return false; } $this->value = KintParser::factory($xml)->extendedValue; $this->type = 'XML'; return true; }
/** * @param mixed $variable * * @return bool */ protected function _parse(&$variable) { if (!is_object($variable)) { return false; } $extendedValue = array(); $reflection = new \ReflectionClass($variable); // first show static values foreach ($reflection->getProperties(\ReflectionProperty::IS_STATIC) as $property) { if ($property->isPrivate()) { if (!method_exists($property, 'setAccessible')) { break; } $property->setAccessible(true); $access = 'private'; } elseif ($property->isProtected()) { $property->setAccessible(true); $access = 'protected'; } else { $access = 'public'; } $_ = $property->getValue(); $output = KintParser::factory($_, '$' . $property->getName()); $output->access = $access; $output->operator = '::'; $extendedValue[] = $output; } foreach ($reflection->getConstants() as $constant => $val) { $output = KintParser::factory($val, $constant); $output->access = 'constant'; $output->operator = '::'; $extendedValue[] = $output; } if (empty($extendedValue)) { return false; } $this->value = $extendedValue; $this->type = 'Static class properties'; $this->size = count($extendedValue); return true; }
/** * @param array $traceData * * @return string */ public static function decorateTrace(array $traceData = array()) { $output = self::_title('TRACE'); $lastStep = count($traceData); foreach ($traceData as $stepNo => $step) { $title = str_pad(++$stepNo . ': ', 4, ' '); $title .= self::_colorize(isset($step['file']) ? self::_buildCalleeString($step) : 'PHP internal call', 'title'); if (!empty($step['function'])) { $title .= ' ' . $step['function']; if (isset($step['args'])) { $title .= '('; if (empty($step['args'])) { $title .= ')'; } $title .= PHP_EOL; } } $output .= $title; if (!empty($step['args'])) { $appendDollar = $step['function'] === '{closure}' ? '' : '$'; $i = 0; foreach ($step['args'] as $name => $argument) { $argument = KintParser::factory($argument, $name ? $appendDollar . $name : '#' . ++$i); $argument->operator = $name ? ' =' : ':'; $maxLevels = Kint::$maxLevels; if ($maxLevels) { Kint::$maxLevels = $maxLevels + 2; } $output .= self::decorate($argument, 2); if ($maxLevels) { Kint::$maxLevels = $maxLevels; } } $output .= ' )' . PHP_EOL; } if (!empty($step['object'])) { $output .= self::_colorize(' ' . self::_char('─', 27) . ' Callee object ' . self::_char('─', 34), 'title'); $maxLevels = Kint::$maxLevels; if ($maxLevels) { # in cli the terminal window is filled too quickly to display huge objects Kint::$maxLevels = Kint::enabled() === Kint::MODE_CLI ? 1 : $maxLevels + 1; } $output .= self::decorate(KintParser::factory($step['object']), 1); if ($maxLevels) { Kint::$maxLevels = $maxLevels; } } if ($stepNo !== $lastStep) { $output .= self::_colorize(self::_char('─', self::$_consoleRow), 'title'); } } return $output; }
/** * @param array $traceData * * @return string * @throws \Exception */ public static function decorateTrace(array $traceData = array()) { $output = '<dl class="kint-trace">'; foreach ($traceData as $i => $step) { $class = ' kint-parent '; if (Kint::$expandedByDefault) { $class .= ' kint-show '; } $output .= ' <dt class="' . $class . '"> <b>' . ($i + 1) . '</b> <nav></nav> <var> '; if (isset($step['file'])) { $output .= self::_ideLink($step['file'], $step['line']); } else { $output .= 'PHP internal call'; } $output .= '</var>'; $output .= $step['function']; if (isset($step['args'])) { $output .= '(' . implode(', ', array_keys($step['args'])) . ')'; } $output .= '</dt><dd>'; $firstTab = ' class="kint-active-tab" '; $output .= '<ul class="kint-tabs">'; if (!empty($step['source'])) { $output .= "<li{$firstTab}>Source</li>"; $firstTab = ''; } if (!empty($step['args'])) { $output .= "<li{$firstTab}>Arguments</li>"; $firstTab = ''; } if (!empty($step['object'])) { KintParser::reset(); $calleeDump = KintParser::factory($step['object']); $output .= "<li{$firstTab}>Callee object [{$calleeDump->type}]</li>"; } $output .= '</ul><ul>'; if (!empty($step['source'])) { $output .= "<li><pre class=\"kint-source\">{$step['source']}</pre></li>"; } if (!empty($step['args'])) { $output .= '<li>'; $j = 0; foreach ($step['args'] as $k => $arg) { KintParser::reset(); if (isset($step['index']) && $step['index'] !== null) { $output .= self::decorate(KintParser::factory($arg, $k), 0, 'debug_backtrace()[' . $step['index'] . "]['args']", 'array', $j); } else { $output .= self::decorate(KintParser::factory($arg, $k)); } $j++; } $output .= '</li>'; } if (isset($calleeDump) && !empty($step['object'])) { $output .= '<li>'; if (isset($step['index']) && $step['index'] !== null) { $output .= self::decorate($calleeDump, 'debug_backtrace(true)[' . $step['index'] . ']', 'array', 'object'); } else { $output .= self::decorate($calleeDump); } $output .= '</li>'; } $output .= '</ul></dd>'; } $output .= '</dl>'; return $output; }
/** * Dump information about variables, accepts any number of parameters, supports modifiers: * * clean up any output before kint and place the dump at the top of page: * - Kint::dump() * ***** * expand all nodes on display: * ! Kint::dump() * ***** * dump variables disregarding their depth: * + Kint::dump() * ***** * return output instead of displaying it: * @ Kint::dump() * ***** * force output as plain text * ~ Kint::dump() * * Modifiers are supported by all dump wrapper functions, including Kint::trace(). Space is optional. * * * You can also use the following shorthand to display debug_backtrace(): * Kint::dump( 1 ); * * Passing the result from debug_backtrace() to kint::dump() as a single parameter will display it as trace too: * $trace = debug_backtrace( true ); * Kint::dump( $trace ); * Or simply: * Kint::dump( debug_backtrace() ); * * * @param mixed $data * * @return void|string */ public static function dump($data = null) { if (!self::enabled()) { return ''; } $stash = self::settings(); list($names, $modifiers, $callee, $previousCaller, $miniTrace) = self::_getCalleeInfo(defined('DEBUG_BACKTRACE_IGNORE_ARGS') ? debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) : debug_backtrace()); # set mode for current run $mode = self::enabled(); if ($mode === true) { $mode = PHP_SAPI === 'cli' && self::$cliDetection === true ? self::MODE_CLI : self::MODE_RICH; } self::enabled($mode); if (strpos($modifiers, '~') !== false) { self::enabled(self::MODE_WHITESPACE); } switch (self::enabled()) { case self::MODE_RICH: $decorator = 'kint\\decorators\\Kint_Decorators_Rich'; break; case self::MODE_JS: $decorator = 'kint\\decorators\\Kint_Decorators_JS'; break; default: case self::MODE_PLAIN: $decorator = 'kint\\decorators\\Kint_Decorators_Plain'; break; } /* @var Kint_Decorators $decorator */ $firstRunOldValue = $decorator::$firstRun; # process modifiers: @, +, ! and - if (strpos($modifiers, '-') !== false) { $decorator::$firstRun = true; while (ob_get_level()) { ob_end_clean(); } } if (strpos($modifiers, '!') !== false) { self::$expandedByDefault = true; } if (strpos($modifiers, '+') !== false) { self::$maxLevels = false; } if (strpos($modifiers, '@') !== false) { self::$returnOutput = true; $decorator::$firstRun = true; } $output = ''; if ($decorator::$firstRun) { $output .= call_user_func(array($decorator, 'init')); } $trace = false; $tmpFuncNumArgs = func_num_args(); if ($data === 1 && $tmpFuncNumArgs === 1 && $names === array(null)) { # Kint::dump(1) shorthand $trace = debug_backtrace(true); } elseif ($tmpFuncNumArgs === 1 && is_array($data)) { $trace = $data; # test if the single parameter is result of debug_backtrace() } $trace and $trace = self::_parseTrace($trace); $output .= call_user_func(array($decorator, 'wrapStart')); if ($trace) { $output .= call_user_func(array($decorator, 'decorateTrace'), $trace); } else { $data = $tmpFuncNumArgs === 0 ? array('[[no arguments passed]]') : func_get_args(); foreach ($data as $k => $argument) { KintParser::reset(); # when the dump arguments take long to generate output, user might have changed the file and # Kint might not parse the arguments correctly, so check if names are set and while the # displayed names might be wrong, at least don't throw an error $output .= call_user_func(array($decorator, 'decorate'), KintParser::factory($argument, isset($names[$k]) ? $names[$k] : '')); } } $output .= call_user_func(array($decorator, 'wrapEnd'), $callee, $miniTrace, $previousCaller); $decorator::$firstRun = false; if (strpos($modifiers, '@') !== false) { $decorator::$firstRun = $firstRunOldValue; } if (self::$returnOutput) { self::settings($stash); return $output; } if (self::$delayedMode) { self::settings($stash); register_shutdown_function('printf', '%s', $output); return ''; } self::settings($stash); echo $output; return ''; }