TraceDebug.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // |
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace think\trace;
  13. use Closure;
  14. use think\App;
  15. use think\Config;
  16. use think\event\LogRecord;
  17. use think\event\LogWrite;
  18. use think\Request;
  19. use think\Response;
  20. use think\response\Redirect;
  21. /**
  22. * 页面Trace中间件
  23. */
  24. class TraceDebug
  25. {
  26. /**
  27. * Trace日志
  28. * @var array
  29. */
  30. protected array $log = [];
  31. /**
  32. * 配置参数
  33. * @var array
  34. */
  35. protected array $config = [];
  36. /** @var App */
  37. protected $app;
  38. public function __construct(App $app, Config $config)
  39. {
  40. $this->app = $app;
  41. $this->config = $config->get('trace');
  42. }
  43. /**
  44. * 页面Trace调试
  45. * @access public
  46. * @param Request $request
  47. * @param Closure $next
  48. * @return void
  49. */
  50. public function handle($request, Closure $next)
  51. {
  52. $debug = $this->app->isDebug();
  53. // 注册日志监听
  54. if ($debug) {
  55. $this->log = [];
  56. $this->app->event->listen(LogWrite::class, function ($event) {
  57. if (empty($this->config['channel']) || $this->config['channel'] == $event->channel) {
  58. $this->parseLog($event->log);
  59. }
  60. });
  61. }
  62. $response = $next($request);
  63. // Trace调试注入
  64. if ($debug) {
  65. $data = $response->getContent();
  66. $this->traceDebug($response, $data);
  67. $response->content($data);
  68. }
  69. return $response;
  70. }
  71. /**
  72. * 解析日志信息
  73. * @access public
  74. * @param array<LogRecord> $log
  75. * @return void
  76. */
  77. protected function parseLog(array $log)
  78. {
  79. foreach ($log as $key => $record) {
  80. if (is_string($key) && is_array($record)) {
  81. $this->log = array_merge_recursive($this->log, $log);
  82. break;
  83. } else {
  84. $this->log[$record->type][] = $record->message;
  85. }
  86. }
  87. }
  88. public function traceDebug(Response $response, &$content)
  89. {
  90. $config = $this->config;
  91. $type = $config['type'] ?? 'Html';
  92. unset($config['type']);
  93. $trace = App::factory($type, '\\think\\trace\\', $config);
  94. if ($response instanceof Redirect) {
  95. //TODO 记录
  96. } else {
  97. $log = $this->app->log->getLog($config['channel'] ?? '');
  98. $this->parseLog($log);
  99. $output = $trace->output($this->app, $response, $this->log);
  100. if (is_string($output)) {
  101. // trace调试信息注入
  102. $pos = strripos($content, '</body>');
  103. if (false !== $pos) {
  104. $content = substr($content, 0, $pos) . $output . substr($content, $pos);
  105. } else {
  106. $content = $content . $output;
  107. }
  108. }
  109. }
  110. }
  111. }