1: | <?php declare(strict_types=1); |
2: | |
3: | namespace Salient\Utility; |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | final class Debug extends AbstractUtility |
11: | { |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | |
25: | |
26: | |
27: | |
28: | public static function getCaller(int $depth = 0): array |
29: | { |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | |
36: | $frames = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, $depth + 3); |
37: | $file = $frames[$depth + 1]['file'] ?? null; |
38: | $line = $frames[$depth + 1]['line'] ?? null; |
39: | $beforeLine = $line !== null ? ':' : null; |
40: | |
41: | if (isset($frames[$depth + 2]['function'])) { |
42: | $frame = $frames[$depth + 2]; |
43: | |
44: | |
45: | if (Str::startsWith($frame['function'], '{closure:')) { |
46: | $closure = implode(':', array_slice(explode(':', $frame['function']), 1, -1)); |
47: | } |
48: | if (isset($frame['class'])) { |
49: | $namespace = Get::namespace($frame['class']); |
50: | $class = Get::basename($frame['class']); |
51: | } else { |
52: | $namespace = Get::namespace($closure ?? $frame['function']); |
53: | $class = ''; |
54: | } |
55: | |
56: | |
57: | $function = isset($closure) |
58: | ? '{closure}' |
59: | : Get::basename($frame['function']); |
60: | if ($namespace !== '') { |
61: | $namespace .= '\\'; |
62: | } |
63: | if ($class !== '' || $namespace !== '') { |
64: | $file = null; |
65: | } |
66: | return Arr::whereNotEmpty([ |
67: | 'namespace' => $namespace, |
68: | 'class' => $class, |
69: | 'file' => $file, |
70: | $frame['type'] ?? ($file !== null ? '::' : null), |
71: | 'function' => $function, |
72: | $beforeLine, |
73: | 'line' => $line, |
74: | ]); |
75: | } |
76: | |
77: | if (isset($frames[$depth + 1])) { |
78: | return Arr::whereNotEmpty([ |
79: | 'file' => $file, |
80: | $beforeLine, |
81: | 'line' => $line, |
82: | ]); |
83: | } |
84: | |
85: | return []; |
86: | } |
87: | } |
88: | |