= 1, round that size if ($set_microtime == -1) { $string .= substr($microtime, 1); } elseif ($set_microtime >= 1) { // in round case we run this through number format to always get the same amount of digits $string .= substr(number_format(round((float)$microtime, $set_microtime), $set_microtime), 1); } return $string; } /** * prints a html formatted (pre) data * * @param mixed $data any data * @param bool $no_html default add
	 * @return string          formatted array for output with 
 tag added
	 */
	public static function printAr(mixed $data, bool $no_html = false): string
	{
		return $no_html ?
			print_r($data, true) :
			'
' . print_r($data, true) . '
'; } /** * alternate name for printAr function * * @param mixed $data any array * @param bool $no_html default add
	 * @return string          formatted array for output with 
 tag added
	 */
	public static function printArray(mixed $data, bool $no_html = false): string
	{
		return self::printAr($data, $no_html);
	}

	/**
	 * A replacement for the \CoreLibs\Debug\Support::printAr
	 * But this does not wrap it in 

	 * Do not use this without using it in a string in debug function
	 * Note: for full data debug dumps use Support::dumpVar()
	 *
	 * @param  mixed  $data Data to print
	 * @return string       print_r formated
	 */
	public static function prAr(mixed $data): string
	{
		return self::printAr($data, true);
	}

	/**
	 * convert bool value to string
	 * if $name is set prefix with nae
	 * default true: true, false: false
	 *
	 * @param  bool   $bool    Variable to convert
	 * @param  string $name    [=''] Prefix name
	 * @param  string $true    [='true'] True string
	 * @param  string $false   [='false'] False string
	 * @param  bool   $no_html [=false] if true do not print html
	 * @return string          String with converted bool text for debug
	 */
	public static function printBool(
		bool $bool,
		string $name = '',
		string $true = 'true',
		string $false = 'false',
		bool $no_html = false,
	): string {
		return
			(!empty($name) ?
				($no_html ?
					$name : '' . $name . '') . ': '
				: '')
			. ($bool ? $true : $false);
	}

	/**
	 * Convert bool value to string value. Short name alias for printBool
	 *
	 * @param  bool   $bool  Bool value to be transformed
	 * @param  string $true  [='true'] Override default string 'true'
	 * @param  string $false [=false'] Override default string 'false'
	 * @return string        $true or $false string for true/false bool
	 */
	public static function prBl(
		bool $bool,
		string $true = 'true',
		string $false = 'false'
	): string {
		return self::printBool($bool, '', $true, $false, true);
	}

	/**
	 * print out any data as string
	 * will convert boolean to TRUE/FALSE
	 * if object return get_class
	 * for array use printAr function, can be controlled with no_html for
	 * Debug\Logging compatible output
	 * Recommended to use Support::dumpVar()
	 *
	 * @param  mixed  $mixed
	 * @param  bool   $no_html set to true to strip 
 tags
	 * @return string
	 */
	public static function printToString(mixed $mixed, bool $no_html = false): string
	{
		if (is_null($mixed)) {
			return (string)'NULL';
		} elseif (is_bool($mixed)) {
			return self::printBool($mixed, '', 'TRUE', 'FALSE');
		} elseif (is_resource($mixed)) {
			return (string)$mixed;
		} elseif (is_object($mixed)) {
			return get_class($mixed);
		} elseif (is_array($mixed)) {
			// use the pre one OR debug one
			return self::printAr($mixed, $no_html);
		} elseif (is_string($mixed)) {
			if ($no_html) {
				return Html::htmlent((string)$mixed);
			} else {
				return (string)$mixed;
			}
		} else {
			// should be int/float/string
			return (string)$mixed;
		}
	}

	/**
	 * Dumps var data and returns it as string
	 * var_dump based
	 * Recommended debug output
	 *
	 * @param  mixed  $data         Anything
	 * @param  bool   $no_html      [=false] If true strip all html tags
	 *                              (for text print)
	 * @return string               A text string
	 */
	public static function dumpVar(
		mixed $data,
		bool $no_html = false,
	): string {
		// dump data
		ob_start();
		var_dump($data);
		$debug_dump = ob_get_clean() ?: '[FAILED TO GET var_dump() data]';
		// check if the original caller is dV, if yes, up the caller level for
		// the file line get by 1, so we get file + pos from the dV call and
		// not this call
		$caller_level = 1;
		$caller_list = self::getCallerMethodList();
		if ($caller_list[0] == 'dV') {
			$caller_level = 2;
		}
		// we need to strip the string in :
		// and replace it with the caller methods and location
		$caller_file_number = self::getCallerFileLine($caller_level);
		$debug_dump = preg_replace(
			'|(/.*:\d+:)|',
			'' . $caller_file_number . ':',
			$debug_dump
		) ?? $debug_dump; // in case of failure keep original
		// if strip is ture, remove all HTML tags and convert any html entities back
		return $no_html ?
			str_replace(
				// things to replace in the string if set
				['>', '<', '
', '
'],
				['>', '<', "\r", "\n"],
				strip_tags($debug_dump)
			) :
			$debug_dump;
	}

	/**
	 * exports (dumps) var, in more printable design, but without detail info
	 *
	 * @param  mixed  $data    Anything
	 * @param  bool   $no_html [=false] If true true do not add 
 tags
	 * @return string          A text string
	 */
	public static function exportVar(mixed $data, bool $no_html = false): string
	{
		return $no_html ?
			var_export($data, true) :
			'
' . var_export($data, true) . '
'; } /** * Return file name and line number where this was called * One level up * * @param int $level [=1] trace level * @return string|null null or file name:line number */ public static function getCallerFileLine(int $level = 1): ?string { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // print \CoreLibs\Debug\Support::printAr($traces); // We should check from top down if unset? // sets the start point here, and in level two (the sub call) we find this if (isset($traces[$level])) { return ($traces[$level]['file'] ?? $traces[$level]['function']) . ':' . ($traces[$level]['line'] ?? '-'); } return null; } /** * if there is a need to find out which parent method called a child method, * eg for debugging, this function does this * * call this method in the child method and you get the parent function that called * @param int $level [=1] trace level * @return string|null null or the function that called the function * where this method is called */ public static function getCallerMethod(int $level = 1): ?string { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // print "getCallerMethod:
" . \CoreLibs\Debug\Support::printAr($traces); // We should check from top down if unset? // sets the start point here, and in level two (the sub call) we find this if (isset($traces[$level])) { return $traces[$level]['function']; } return null; } /** * get the class that first called it and skip the base class * Companion method to getCallerMethod * * @param int $level [=1] trace level * @return ?string null if class not found */ public static function getCallerClass(int $level = 1): ?string { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // print "getCallerClass:
" . \CoreLibs\Debug\Support::printAr($traces); if (isset($traces[$level])) { return $traces[$level]['class'] ?? null; } return null; } /** * Returns class and method together * * @param int $level [=1] travel level * @return string|null null if trace level not found, else namespace class and method */ public static function getCallerClassMethod(int $level = 1): ?string { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // print "getCallerClass:
" . \CoreLibs\Debug\Support::printAr($traces); if (isset($traces[$level])) { return ($traces[$level]['class'] ?? '-') . ($traces[$level]['type'] ?? '') . $traces[$level]['function']; } return null; } /** * Returns array with all methods in the call stack in the order so that last * called is last in order * Will start with start_level to skip unwanted from stack * Defaults to skip level 0 wich is this methid * * @param integer $start_level [=1] From what level on, starts with 1 to exclude self * @return array All method names in list where max is last called */ public static function getCallerMethodList(int $start_level = 1): array { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $methods = []; foreach ($traces as $level => $data) { if ($level < $start_level) { continue; } if (!empty($data['function'])) { array_unshift($methods, $data['function']); } } return $methods; } /** * Get the full call stack from a certain starting level * The return string is * file:line:class->method * * Note that '::' is used for static calls * * @param int $start_level [=1] starts with 1 to exclude itself * @return array string with file, line, class and method */ public static function getCallStack(int $start_level = 1): array { $call_stack = []; $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); foreach ($backtrace as $level => $call_trace) { if ($level < $start_level) { continue; } $call_stack[] = ($call_trace['file'] ?? 'n/f') . ':' . ($call_trace['line'] ?? '-') . ':' . (!empty($call_trace['class']) ? $call_trace['class'] . ($call_trace['type'] ?? '') : '' ) . $call_trace['function']; } return $call_stack; } /** * Get the current class where this function is called * Is mostly used in debug log statements to get the class where the debug * was called * gets top level class * loops over the debug backtrace until if finds the first class (from the end) * * @return string Class name with namespace */ public static function getCallerTopLevelClass(): string { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // print "getCallerClass:
" . \CoreLibs\Debug\Support::printAr($traces); $class = null; // reverse and stop at first set class, this is the top level one foreach (array_reverse($traces) as $trace) { $class = $trace['class'] ?? null; if (!empty($class)) { break; } } // on null or empty return empty string return empty($class) ? '' : $class; } /** * If a string is empty, sets '-' for return, or if given any other string * * @param string|null $string The string to check * @param string $replace [default '-'] What to replace the empty string with * @return string String itself or the replaced value */ public static function debugString( ?string $string, string $replace = '-', bool $no_html = false ): string { if (empty($string)) { $string = $replace; } if ($no_html) { return Html::htmlent($string); } else { return $string; } } } // __END__