DebugHelper.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * 调试辅助脚本,目前主要集中在输出功能.
  5. * @version
  6. * 2.0.1 添加检查PHP version和extensions的方法. --gwang 2019年8月16日 15:15:48
  7. * 1.0.0 Created at 2016-7-1. by --gwang
  8. * @author gwang (mail@wanggangzero.cn)
  9. * @copyright © 2016-7-1, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  10. */
  11. class DebugHelper {
  12. /**
  13. * @return bool 调试输出是否开启
  14. */
  15. private static function isDebugging() {
  16. return defined("GAME_ONLINE") && !GAME_ONLINE; # 线上版屏蔽输出
  17. }
  18. /**
  19. * 尝试从array中取出一个命名变量, Ps.可以取消5.3中的Notice
  20. * @param arry $arr
  21. * @param string $strFieldName
  22. * @return mixed
  23. */
  24. private static function arr_get($arr, $strFieldName) {
  25. if (isset($arr[$strFieldName])) {
  26. return $arr[$strFieldName];
  27. }
  28. return null;
  29. }
  30. //
  31. // <editor-fold defaultstate="collapsed" desc="assert">
  32. /**
  33. * 逻辑断言,不受系统断言状态影响,可以用于生产环境的简单判断,比如:参数非法,参数缺失等
  34. * @param type $condition
  35. * @param int/string $err 如果是int值,则当作Errcode处理,否则当作字符串处理
  36. */
  37. static function assert($condition, $err) {
  38. if (!$condition) { # 断言失败
  39. if (is_int($err)) { # err是int值,则按照错误码查找错误提示信息
  40. $errMsg = GameConfig::errmsg_getItem($err);
  41. $msg = "";
  42. if (null != $errMsg) {
  43. $msg = $errMsg->msg;
  44. }
  45. Err($err, "$msg" . self::get_call_stack(6));
  46. } else { # 不是int值,则当做普通错误信息来处理
  47. Err(ErrCode::err_assert, $err . self::get_call_stack(6));
  48. }
  49. }
  50. }
  51. /**
  52. * 接管系统的断言失败处理函数(调试用,若要检查参数是否完整,请用Resp::assert())
  53. * 注意:方法内部依赖于GAME_ONLINE标志,若为内网调试则打开断言,
  54. * 若为线上环境则关闭断言(提升安全性和部分性能)
  55. */
  56. static function cover_assert_handler() {
  57. assert_options(ASSERT_ACTIVE, !GAME_ONLINE); # 设置断言标志
  58. assert_options(ASSERT_BAIL, true);
  59. assert_options(ASSERT_WARNING, false);
  60. assert_options(ASSERT_CALLBACK, array('DebugHelper', 'my_assert_handler')); # 设置回调函数
  61. }
  62. /**
  63. * 断言处理函数
  64. * @param type $file
  65. * @param type $line
  66. * @param type $code
  67. * @param type $desc
  68. */
  69. private static function my_assert_handler($file, $line, $code, $desc) {
  70. $msg = "<hr>Assertion Failed:
  71. File '$file'<br />
  72. Line '$line'<br />
  73. Code '$code'<br />
  74. Desc '{$desc}'<br />
  75. <hr />";
  76. Err(Err::err_assert, $msg); # 给客户端返回值
  77. // trigger_error($msg, E_USER_ERROR); # 抛出一个err
  78. }
  79. // </editor-fold>
  80. //
  81. /**
  82. * 浏览器打印调试信息
  83. * @param mixed $msg 对象或数组将会被序列化为json串
  84. */
  85. public static function debug($msg) {
  86. if (self::isDebugging()) {
  87. if (is_array($msg) || is_object($msg)) {
  88. $msg = json_encode($msg);
  89. }
  90. echoLine('[' . TimeUtil::dtCurrent() . ']| ' . $msg);
  91. }
  92. }
  93. /**
  94. * var_dump输出变量,统一入口的话, 上线的时候通过统一变量关闭,防止漏删除的意外输出.
  95. * @param mixed $obj
  96. */
  97. public static function var_dump($obj) {
  98. if (!self::isDebugging()) {
  99. return;
  100. }
  101. $pos = self::get_call_stack();
  102. $stack = explode('<br/>', $pos);
  103. $n = 3 > count($stack) ? count($stack) : 3;
  104. for ($i = 0; $i < $n; $i++) {
  105. echoLine($stack[$i]);
  106. }
  107. echoLine(); # 换个行
  108. var_dump($obj);
  109. }
  110. /**
  111. * 浏览器输出调用堆栈
  112. * @return void
  113. */
  114. public static function print_stack_trace() {
  115. /* * * * *
  116. * 因为debug_print_backtrace()格式不太易读,自己调整下输出样式
  117. * * * */
  118. $html = self::get_call_stack();
  119. self::debug($html);
  120. }
  121. /**
  122. * 获得调用堆栈
  123. * @param int $levelnum 想要获得的调用层次,default is 3
  124. * @return string formated string
  125. */
  126. static public function get_call_stack($levelnum = 3) {
  127. $array = debug_backtrace();
  128. $outHtml = PHP_EOL;
  129. array_shift($array); # 移除get_call_stack函数自身
  130. $n = 1;
  131. foreach ($array as $row) {
  132. $outHtml .= "\t" . CommUtil::str2UTF8(self::arr_get($row, 'file')) # windows下路径(gb2312)转码
  133. . ', row: ' . self::arr_get($row, 'line') . ', method: ' # line
  134. . self::arr_get($row, 'function') . ";<br/>" . PHP_EOL; # func
  135. if ($levelnum <= $n++) {
  136. break;
  137. }
  138. }
  139. return $outHtml;
  140. }
  141. /**
  142. * 浏览器弹窗提示
  143. * @param string $msg
  144. */
  145. public static function alert($msg) {
  146. if (self::isDebugging()) {
  147. echo "<Script language=\"javascript\">alert(\"" . $msg . "\");</Script>";
  148. }
  149. }
  150. }