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
						
					
					
				<?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 (\Phacil\Framework\Config::DIR_APPLICATION()) {
 | 
						|
				self::$_filePath = \Phacil\Framework\Config::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;
 | 
						|
	}
 | 
						|
} |