PluginProbe
Black Bar / trunk
Black Bar vtrunk
trunk 1.0.0 1.1.0 1.2.0 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.2.0 2.2.1 3.0.0 3.1.0 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0
blackbar / plugin / Dump.php

Dump.php in Black Bar trunk, at plugin/Dump.php

148 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace GeminiLabs\BlackBar;
4
5 /**
6 * @see: https://github.com/jacobstr/dumpling
7 */
8 class Dump
9 {
10 public $depth;
11 public $ignore;
12
13 protected $level = 0;
14 protected $result = [];
15 protected $stack = [];
16
17 /**
18 * @param mixed $value
19 */
20 public function dump($value, int $depth = 3, array $ignore = []): string
21 {
22 $this->depth = $depth;
23 $this->ignore = $ignore;
24 $this->reset();
25 $this->inspect($value);
26 $result = implode('', $this->result);
27 $result = rtrim($result, "\n");
28 $this->reset();
29 return $result;
30 }
31
32 protected function formatKey(string $key): string
33 {
34 $result = [];
35 $result[] = str_repeat(' ', $this->level * 4).'[';
36 if ("\0" === $key[0]) {
37 $keyParts = explode("\0", $key);
38 $result[] = $keyParts[2].(('*' === $keyParts[1]) ? ':protected' : ':private');
39 } else {
40 $result[] = $key;
41 }
42 $result[] = '] => ';
43 return implode('', $result);
44 }
45
46 /**
47 * @param mixed $subject
48 */
49 protected function inspect($subject): void
50 {
51 ++$this->level;
52 if ($subject instanceof \Closure) {
53 $this->inspectClosure($subject);
54 } elseif (is_object($subject)) {
55 $this->inspectObject($subject);
56 } elseif (is_array($subject)) {
57 $this->inspectArray($subject);
58 } else {
59 $this->inspectPrimitive($subject);
60 }
61 --$this->level;
62 }
63
64 protected function inspectArray(array $subject): void
65 {
66 if ($this->level > $this->depth) {
67 $this->result[] = "Nested Array\n";
68 return;
69 }
70 if (empty($subject)) {
71 $this->result[] = "Array ()\n";
72 return;
73 }
74 $this->result[] = "Array (\n";
75 foreach ($subject as $key => $val) {
76 if (false === $this->isIgnoredKey($key)) {
77 $this->result[] = str_repeat(' ', $this->level * 4).'['.$key.'] => ';
78 $this->inspect($val);
79 }
80 }
81 $this->result[] = str_repeat(' ', ($this->level - 1) * 4).")\n";
82 }
83
84 protected function inspectClosure(\Closure $subject): void
85 {
86 $reflection = new \ReflectionFunction($subject);
87 $params = array_map(function ($param) {
88 return ($param->isPassedByReference() ? '&$' : '$').$param->name;
89 }, $reflection->getParameters());
90 $this->result[] = 'Closure ('.implode(', ', $params).') { ... }'."\n";
91 }
92
93 /**
94 * @param object $subject
95 */
96 protected function inspectObject($subject): void
97 {
98 $classname = get_class($subject);
99 if ($this->level > $this->depth) {
100 $this->result[] = 'Nested '.$classname." Object\n";
101 return;
102 }
103 if ($subject instanceof \ArrayObject) {
104 $this->result[] = $classname." ArrayObject (\n";
105 } else {
106 $this->result[] = $classname." Object (\n";
107 $subject = (array) $subject;
108 }
109 foreach ($subject as $key => $val) {
110 if (!$this->isIgnoredKey($key)) {
111 $this->result[] = $this->formatKey($key);
112 $this->inspect($val);
113 }
114 }
115 $this->result[] = str_repeat(' ', ($this->level - 1) * 4).")\n";
116 }
117
118 /**
119 * @param mixed $subject
120 */
121 protected function inspectPrimitive($subject): void
122 {
123 if (true === $subject) {
124 $subject = '(bool) true';
125 } elseif (false === $subject) {
126 $subject = '(bool) false';
127 } elseif (null === $subject) {
128 $subject = '(null)';
129 }
130 $this->result[] = $subject."\n";
131 }
132
133 /**
134 * @param mixed $key
135 */
136 protected function isIgnoredKey($key): bool
137 {
138 return !is_scalar($key) || in_array($key, $this->ignore);
139 }
140
141 protected function reset(): void
142 {
143 $this->level = 0;
144 $this->result = [];
145 $this->stack = [];
146 }
147 }
148