A super easy PHP Framework for web development!
https://github.com/exacti/phacil-framework
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.4 KiB
191 lines
4.4 KiB
3 years ago
|
<?php
|
||
|
/**
|
||
|
* Copyright © 2022 ExacTI Technology Solutions. All rights reserved.
|
||
|
* GPLv3 General License.
|
||
|
* https://exacti.com.br
|
||
|
* Phacil PHP Framework - https://github.com/exacti/phacil-framework
|
||
|
* @author Bruno O. Notario <oliveira131@hotmail.com>
|
||
|
*/
|
||
|
|
||
|
namespace Phacil\Framework;
|
||
|
|
||
|
/**
|
||
|
* Debug methods
|
||
|
* @package Phacil\Framework
|
||
|
*/
|
||
|
class Debug
|
||
|
{
|
||
|
/**
|
||
|
* @var int
|
||
|
*/
|
||
|
public static $argLength = 16;
|
||
|
|
||
|
/**
|
||
|
* Root path
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
protected static $_filePath;
|
||
|
|
||
|
/**
|
||
|
* Retrieve real root path with last directory separator
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function getRootPath()
|
||
|
{
|
||
|
if (self::$_filePath === null) {
|
||
|
if (defined('DIR_APPLICATION')) {
|
||
|
self::$_filePath = DIR_APPLICATION;
|
||
|
} else {
|
||
|
self::$_filePath = dirname(__DIR__);
|
||
|
}
|
||
|
}
|
||
|
return self::$_filePath;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prints or returns a backtrace
|
||
|
*
|
||
|
* @param bool $return return or print
|
||
|
* @param bool $html output in HTML format
|
||
|
* @param bool $withArgs add short arguments of methods
|
||
|
* @return string|bool
|
||
|
*/
|
||
|
public static function backtrace($return = false, $html = true, $withArgs = true)
|
||
|
{
|
||
|
$trace = debug_backtrace();
|
||
|
return self::trace($trace, $return, $html, $withArgs);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prints or return a trace
|
||
|
*
|
||
|
* @param array $trace trace array
|
||
|
* @param bool $return return or print
|
||
|
* @param bool $html output in HTML format
|
||
|
* @param bool $withArgs add short arguments of methods
|
||
|
* @return string|bool
|
||
|
*/
|
||
|
public static function trace(array $trace, $return = true, $html = false, $withArgs = true)
|
||
|
{
|
||
|
$out = '';
|
||
|
if ($html) {
|
||
|
$out .= '<pre>';
|
||
|
}
|
||
|
|
||
|
foreach ($trace as $i => $data) {
|
||
|
// skip self
|
||
|
if ($i == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// prepare method arguments
|
||
|
$args = [];
|
||
|
if (isset($data['args']) && $withArgs) {
|
||
|
foreach ($data['args'] as $arg) {
|
||
|
$args[] = self::_formatCalledArgument($arg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// prepare method's name
|
||
|
if (isset($data['class']) && isset($data['function'])) {
|
||
|
if (isset($data['object']) && get_class($data['object']) != $data['class']) {
|
||
|
$className = get_class($data['object']) . '[' . $data['class'] . ']';
|
||
|
} else {
|
||
|
$className = $data['class'];
|
||
|
}
|
||
|
if (isset($data['object'])) {
|
||
|
$className .= sprintf('#%s#', spl_object_hash($data['object']));
|
||
|
}
|
||
|
|
||
|
$methodName = sprintf(
|
||
|
'%s%s%s(%s)',
|
||
|
$className,
|
||
|
isset($data['type']) ? $data['type'] : '->',
|
||
|
$data['function'],
|
||
|
join(', ', $args)
|
||
|
);
|
||
|
} elseif (isset($data['function'])) {
|
||
|
$methodName = sprintf('%s(%s)', $data['function'], join(', ', $args));
|
||
|
}
|
||
|
|
||
|
if (isset($data['file'])) {
|
||
|
$pos = strpos($data['file'], self::getRootPath());
|
||
|
if ($pos !== false) {
|
||
|
$data['file'] = str_replace(self::getRootPath(), "", $data['file']);
|
||
|
}
|
||
|
$fileName = sprintf('%s:%d', $data['file'], $data['line']);
|
||
|
} else {
|
||
|
$fileName = false;
|
||
|
}
|
||
|
|
||
|
if ($fileName) {
|
||
|
$out .= sprintf('#%d %s called at [%s]', $i, $methodName, $fileName);
|
||
|
} else {
|
||
|
$out .= sprintf('#%d %s', $i, $methodName);
|
||
|
}
|
||
|
|
||
|
$out .= "\n";
|
||
|
}
|
||
|
|
||
|
if ($html) {
|
||
|
$out .= '</pre>';
|
||
|
}
|
||
|
|
||
|
if ($return) {
|
||
|
return $out;
|
||
|
} else {
|
||
|
echo $out;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Format argument in called method
|
||
|
*
|
||
|
* @param mixed $arg
|
||
|
* @return string
|
||
|
*/
|
||
|
protected static function _formatCalledArgument($arg)
|
||
|
{
|
||
|
$out = '';
|
||
|
if (is_object($arg)) {
|
||
|
$out .= sprintf("&%s#%s#", get_class($arg), spl_object_hash($arg));
|
||
|
} elseif (is_resource($arg)) {
|
||
|
$out .= '#[' . get_resource_type($arg) . ']';
|
||
|
} elseif (is_array($arg)) {
|
||
|
$isAssociative = false;
|
||
|
$args = [];
|
||
|
foreach ($arg as $k => $v) {
|
||
|
if (!is_numeric($k)) {
|
||
|
$isAssociative = true;
|
||
|
}
|
||
|
$args[$k] = self::_formatCalledArgument($v);
|
||
|
}
|
||
|
if ($isAssociative) {
|
||
|
$arr = [];
|
||
|
foreach ($args as $k => $v) {
|
||
|
$arr[] = self::_formatCalledArgument($k) . ' => ' . $v;
|
||
|
}
|
||
|
$out .= 'array(' . join(', ', $arr) . ')';
|
||
|
} else {
|
||
|
$out .= 'array(' . join(', ', $args) . ')';
|
||
|
}
|
||
|
} elseif ($arg === null) {
|
||
|
$out .= 'NULL';
|
||
|
} elseif (is_numeric($arg) || is_float($arg)) {
|
||
|
$out .= $arg;
|
||
|
} elseif (is_string($arg)) {
|
||
|
if (strlen($arg) > self::$argLength) {
|
||
|
$arg = substr($arg, 0, self::$argLength) . "...";
|
||
|
}
|
||
|
$arg = strtr($arg, ["\t" => '\t', "\r" => '\r', "\n" => '\n', "'" => '\\\'']);
|
||
|
$out .= "'" . $arg . "'";
|
||
|
} elseif (is_bool($arg)) {
|
||
|
$out .= $arg === true ? 'true' : 'false';
|
||
|
}
|
||
|
|
||
|
return $out;
|
||
|
}
|
||
|
}
|