Skip to content

Commit e7b4441

Browse files
committed
Dumper: static -> object class
1 parent 6e1cc8d commit e7b4441

File tree

8 files changed

+100
-79
lines changed

8 files changed

+100
-79
lines changed

readme.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,17 @@ $closure = Nette\PhpGenerator\Closure::from(
550550
function (stdClass $a, $b = null) {}
551551
);
552552
```
553+
554+
Variables dumper
555+
----------------
556+
557+
The Dumper returns a parsable PHP string representation of a variable. It provides a better function that you can use instead of `var_export()`
558+
with more readable output.
559+
560+
```php
561+
$dumper = new Nette\PhpGenerator\Dumper;
562+
563+
$var = ['a', 'b', 123];
564+
565+
echo $dumper->dump($var); // prints ['a', 'b', 123]
566+
```

src/PhpGenerator/Dumper.php

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
*/
1818
final class Dumper
1919
{
20-
use Nette\StaticClass;
21-
2220
public const WRAP_LENGTH = 100;
2321

2422
private const INDENT_LENGTH = 4;
@@ -29,13 +27,13 @@ final class Dumper
2927
/**
3028
* Returns a PHP representation of a variable.
3129
*/
32-
public static function dump($var): string
30+
public function dump($var): string
3331
{
34-
return self::_dump($var);
32+
return $this->_dump($var);
3533
}
3634

3735

38-
private static function _dump(&$var, int $level = 0)
36+
private function _dump(&$var, int $level = 0)
3937
{
4038
if ($var instanceof PhpLiteral) {
4139
return (string) $var;
@@ -84,7 +82,7 @@ private static function _dump(&$var, int $level = 0)
8482
$counter = 0;
8583
foreach ($var as $k => &$v) {
8684
if ($k !== $marker) {
87-
$item = ($k === $counter ? '' : self::_dump($k, $level + 1) . ' => ') . self::_dump($v, $level + 1);
85+
$item = ($k === $counter ? '' : $this->_dump($k, $level + 1) . ' => ') . $this->_dump($v, $level + 1);
8886
$counter = is_int($k) ? max($k + 1, $counter) : $counter;
8987
$out .= ($out === '' ? '' : ', ') . $item;
9088
$outWrapped .= "\t$item,\n$space";
@@ -97,7 +95,7 @@ private static function _dump(&$var, int $level = 0)
9795

9896
} elseif ($var instanceof \Serializable) {
9997
$var = serialize($var);
100-
return 'unserialize(' . self::_dump($var, $level) . ')';
98+
return 'unserialize(' . $this->_dump($var, $level) . ')';
10199

102100
} elseif ($var instanceof \Closure) {
103101
throw new Nette\InvalidArgumentException('Cannot dump closure.');
@@ -108,7 +106,7 @@ private static function _dump(&$var, int $level = 0)
108106
throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');
109107

110108
} elseif (in_array($class, ['DateTime', 'DateTimeImmutable'], true)) {
111-
return self::format("new $class(?, new DateTimeZone(?))", $var->format('Y-m-d H:i:s.u'), $var->getTimeZone()->getName());
109+
return $this->format("new $class(?, new DateTimeZone(?))", $var->format('Y-m-d H:i:s.u'), $var->getTimeZone()->getName());
112110
}
113111

114112
$arr = (array) $var;
@@ -128,7 +126,7 @@ private static function _dump(&$var, int $level = 0)
128126
}
129127
foreach ($arr as $k => &$v) {
130128
if (!isset($props) || isset($props[$k])) {
131-
$out .= "$space\t" . self::_dump($k, $level + 1) . ' => ' . self::_dump($v, $level + 1) . ",\n";
129+
$out .= "$space\t" . $this->_dump($k, $level + 1) . ' => ' . $this->_dump($v, $level + 1) . ",\n";
132130
}
133131
}
134132
array_pop($list);
@@ -150,7 +148,7 @@ private static function _dump(&$var, int $level = 0)
150148
/**
151149
* Generates PHP statement.
152150
*/
153-
public static function format(string $statement, ...$args): string
151+
public function format(string $statement, ...$args): string
154152
{
155153
$tokens = preg_split('#(\.\.\.\?|\$\?|->\?|::\?|\\\\\?|\?\*|\?)#', $statement, -1, PREG_SPLIT_DELIM_CAPTURE);
156154
$res = '';
@@ -162,22 +160,22 @@ public static function format(string $statement, ...$args): string
162160
} elseif (!$args) {
163161
throw new Nette\InvalidArgumentException('Insufficient number of arguments.');
164162
} elseif ($token === '?') {
165-
$res .= self::dump(array_shift($args));
163+
$res .= $this->dump(array_shift($args));
166164
} elseif ($token === '...?' || $token === '?*') {
167165
$arg = array_shift($args);
168166
if (!is_array($arg)) {
169167
throw new Nette\InvalidArgumentException('Argument must be an array.');
170168
}
171169
$items = [];
172170
foreach ($arg as $tmp) {
173-
$items[] = self::dump($tmp);
171+
$items[] = $this->dump($tmp);
174172
}
175173
$res .= strlen($tmp = implode(', ', $items)) > self::WRAP_LENGTH && count($items) > 1
176174
? "\n" . Nette\Utils\Strings::indent(implode(",\n", $items)) . "\n"
177175
: $tmp;
178176

179177
} else { // $ -> ::
180-
$res .= substr($token, 0, -1) . self::formatMember(array_shift($args));
178+
$res .= substr($token, 0, -1) . $this->formatMember(array_shift($args));
181179
}
182180
}
183181
if ($args) {
@@ -190,10 +188,10 @@ public static function format(string $statement, ...$args): string
190188
/**
191189
* Returns a PHP representation of a object member.
192190
*/
193-
private static function formatMember($name): string
191+
private function formatMember($name): string
194192
{
195193
return $name instanceof PhpLiteral || !Helpers::isIdentifier($name)
196-
? '{' . self::_dump($name) . '}'
194+
? '{' . $this->_dump($name) . '}'
197195
: $name;
198196
}
199197

src/PhpGenerator/Helpers.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ final class Helpers
2525
/** @deprecated use Nette\PhpGenerator\Dumper::dump() */
2626
public static function dump($var): string
2727
{
28-
return Dumper::dump($var);
28+
return (new Dumper)->dump($var);
2929
}
3030

3131

3232
/** @deprecated use Nette\PhpGenerator\Dumper::format() */
3333
public static function format(string $statement, ...$args): string
3434
{
35-
return Dumper::format($statement, ...$args);
35+
return (new Dumper)->format($statement, ...$args);
3636
}
3737

3838

3939
/** @deprecated use Nette\PhpGenerator\Dumper::format() */
4040
public static function formatArgs(string $statement, array $args): string
4141
{
42-
return Dumper::format($statement, ...$args);
42+
return (new Dumper)->format($statement, ...$args);
4343
}
4444

4545

src/PhpGenerator/Method.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function __toString(): string
6666
*/
6767
public function setBody(?string $code, array $args = null): self
6868
{
69-
$this->body = $args === null || $code === null ? $code : Dumper::format($code, ...$args);
69+
$this->body = $args === null || $code === null ? $code : (new Dumper)->format($code, ...$args);
7070
return $this;
7171
}
7272

src/PhpGenerator/Printer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ protected function indent(string $s): string
216216

217217
protected function dump($var): string
218218
{
219-
return Dumper::dump($var);
219+
return (new Dumper)->dump($var);
220220
}
221221

222222

src/PhpGenerator/Traits/FunctionLike.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ trait FunctionLike
4343
*/
4444
public function setBody(string $code, array $args = null): self
4545
{
46-
$this->body = $args === null ? $code : Dumper::format($code, ...$args);
46+
$this->body = $args === null ? $code : (new Dumper)->format($code, ...$args);
4747
return $this;
4848
}
4949

@@ -59,7 +59,7 @@ public function getBody(): string
5959
*/
6060
public function addBody(string $code, array $args = null): self
6161
{
62-
$this->body .= ($args === null ? $code : Dumper::format($code, ...$args)) . "\n";
62+
$this->body .= ($args === null ? $code : (new Dumper)->format($code, ...$args)) . "\n";
6363
return $this;
6464
}
6565

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
/**
4-
* Test: Nette\PhpGenerator\::dump()
4+
* Test: Nette\PhpGenerator\Dumper::dump()
55
*/
66

77
declare(strict_types=1);
@@ -15,41 +15,42 @@ require __DIR__ . '/../bootstrap.php';
1515

1616
ini_set('serialize_precision', '14');
1717

18-
Assert::same('0', Dumper::dump(0));
19-
Assert::same('1', Dumper::dump(1));
20-
Assert::same('0.0', Dumper::dump(0.0));
21-
Assert::same('1.0', Dumper::dump(1.0));
22-
Assert::same('0.1', Dumper::dump(0.1));
23-
Assert::same('INF', Dumper::dump(INF));
24-
Assert::same('-INF', Dumper::dump(-INF));
25-
Assert::same('NAN', Dumper::dump(NAN));
26-
Assert::same('null', Dumper::dump(null));
27-
Assert::same('true', Dumper::dump(true));
28-
Assert::same('false', Dumper::dump(false));
29-
30-
Assert::same("''", Dumper::dump(''));
31-
Assert::same("'Hello'", Dumper::dump('Hello'));
32-
Assert::same('"\t\n\t"', Dumper::dump("\t\n\t"));
33-
Assert::same("'I\u{F1}t\u{EB}rn\u{E2}ti\u{F4}n\u{E0}liz\u{E6}ti\u{F8}n'", Dumper::dump("I\u{F1}t\u{EB}rn\u{E2}ti\u{F4}n\u{E0}liz\u{E6}ti\u{F8}n")); // Iñtërnâtiônàlizætiøn
34-
Assert::same('"\rHello \$"', Dumper::dump("\rHello $"));
35-
Assert::same("'He\\llo'", Dumper::dump('He\llo'));
36-
Assert::same('\'He\ll\\\\\o \\\'wor\\\\\\\'ld\\\\\'', Dumper::dump('He\ll\\\o \'wor\\\'ld\\'));
37-
Assert::same('[]', Dumper::dump([]));
38-
39-
Assert::same('[$s]', Dumper::dump([new PhpLiteral('$s')]));
40-
41-
Assert::same('[1, 2, 3]', Dumper::dump([1, 2, 3]));
42-
Assert::same("['a', 7 => 'b', 'c', '9a' => 'd', 'e']", Dumper::dump(['a', 7 => 'b', 'c', '9a' => 'd', 9 => 'e']));
18+
$dumper = new Dumper;
19+
Assert::same('0', $dumper->dump(0));
20+
Assert::same('1', $dumper->dump(1));
21+
Assert::same('0.0', $dumper->dump(0.0));
22+
Assert::same('1.0', $dumper->dump(1.0));
23+
Assert::same('0.1', $dumper->dump(0.1));
24+
Assert::same('INF', $dumper->dump(INF));
25+
Assert::same('-INF', $dumper->dump(-INF));
26+
Assert::same('NAN', $dumper->dump(NAN));
27+
Assert::same('null', $dumper->dump(null));
28+
Assert::same('true', $dumper->dump(true));
29+
Assert::same('false', $dumper->dump(false));
30+
31+
Assert::same("''", $dumper->dump(''));
32+
Assert::same("'Hello'", $dumper->dump('Hello'));
33+
Assert::same('"\t\n\t"', $dumper->dump("\t\n\t"));
34+
Assert::same("'I\u{F1}t\u{EB}rn\u{E2}ti\u{F4}n\u{E0}liz\u{E6}ti\u{F8}n'", $dumper->dump("I\u{F1}t\u{EB}rn\u{E2}ti\u{F4}n\u{E0}liz\u{E6}ti\u{F8}n")); // Iñtërnâtiônàlizætiøn
35+
Assert::same('"\rHello \$"', $dumper->dump("\rHello $"));
36+
Assert::same("'He\\llo'", $dumper->dump('He\llo'));
37+
Assert::same('\'He\ll\\\\\o \\\'wor\\\\\\\'ld\\\\\'', $dumper->dump('He\ll\\\o \'wor\\\'ld\\'));
38+
Assert::same('[]', $dumper->dump([]));
39+
40+
Assert::same('[$s]', $dumper->dump([new PhpLiteral('$s')]));
41+
42+
Assert::same('[1, 2, 3]', $dumper->dump([1, 2, 3]));
43+
Assert::same("['a', 7 => 'b', 'c', '9a' => 'd', 'e']", $dumper->dump(['a', 7 => 'b', 'c', '9a' => 'd', 9 => 'e']));
4344
same("[
4445
[
4546
'a',
4647
'loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong',
4748
],
48-
]", Dumper::dump([['a', 'loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong']]));
49-
Assert::same("['a' => 1, [\"\\r\" => \"\\r\", 2], 3]", Dumper::dump(['a' => 1, ["\r" => "\r", 2], 3]));
49+
]", $dumper->dump([['a', 'loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong']]));
50+
Assert::same("['a' => 1, [\"\\r\" => \"\\r\", 2], 3]", $dumper->dump(['a' => 1, ["\r" => "\r", 2], 3]));
5051

51-
Assert::same("(object) [\n\t'a' => 1,\n\t'b' => 2,\n]", Dumper::dump((object) ['a' => 1, 'b' => 2]));
52-
Assert::same("(object) [\n\t'a' => (object) [\n\t\t'b' => 2,\n\t],\n]", Dumper::dump((object) ['a' => (object) ['b' => 2]]));
52+
Assert::same("(object) [\n\t'a' => 1,\n\t'b' => 2,\n]", $dumper->dump((object) ['a' => 1, 'b' => 2]));
53+
Assert::same("(object) [\n\t'a' => (object) [\n\t\t'b' => 2,\n\t],\n]", $dumper->dump((object) ['a' => (object) ['b' => 2]]));
5354

5455

5556
class Test
@@ -61,8 +62,8 @@ class Test
6162
private $c = 3;
6263
}
6364

64-
Assert::same("Nette\\PhpGenerator\\Dumper::createObject('Test', [\n\t'a' => 1,\n\t\"\\x00*\\x00b\" => 2,\n\t\"\\x00Test\\x00c\" => 3,\n])", Dumper::dump(new Test));
65-
Assert::equal(new Test, eval('return ' . Dumper::dump(new Test) . ';'));
65+
Assert::same("Nette\\PhpGenerator\\Dumper::createObject('Test', [\n\t'a' => 1,\n\t\"\\x00*\\x00b\" => 2,\n\t\"\\x00Test\\x00c\" => 3,\n])", $dumper->dump(new Test));
66+
Assert::equal(new Test, eval('return ' . $dumper->dump(new Test) . ';'));
6667

6768

6869
class Test2 extends Test
@@ -83,8 +84,8 @@ class Test2 extends Test
8384
}
8485
}
8586

86-
Assert::same("Nette\\PhpGenerator\\Dumper::createObject('Test2', [\n\t\"\\x00Test2\\x00c\" => 4,\n\t'a' => 1,\n\t\"\\x00*\\x00b\" => 2,\n])", Dumper::dump(new Test2));
87-
Assert::equal(new Test2, eval('return ' . Dumper::dump(new Test2) . ';'));
87+
Assert::same("Nette\\PhpGenerator\\Dumper::createObject('Test2', [\n\t\"\\x00Test2\\x00c\" => 4,\n\t'a' => 1,\n\t\"\\x00*\\x00b\" => 2,\n])", $dumper->dump(new Test2));
88+
Assert::equal(new Test2, eval('return ' . $dumper->dump(new Test2) . ';'));
8889

8990

9091
class Test3 implements Serializable
@@ -103,11 +104,12 @@ class Test3 implements Serializable
103104
}
104105
}
105106

106-
Assert::same('unserialize(\'C:5:"Test3":0:{}\')', Dumper::dump(new Test3));
107-
Assert::equal(new Test3, eval('return ' . Dumper::dump(new Test3) . ';'));
107+
Assert::same('unserialize(\'C:5:"Test3":0:{}\')', $dumper->dump(new Test3));
108+
Assert::equal(new Test3, eval('return ' . $dumper->dump(new Test3) . ';'));
108109

109110
Assert::exception(function () {
110-
Dumper::dump(function () {});
111+
$dumper = new Dumper;
112+
$dumper->dump(function () {});
111113
}, Nette\InvalidArgumentException::class, 'Cannot dump closure.');
112114

113115

@@ -118,36 +120,39 @@ class TestDateTime extends DateTime
118120

119121
Assert::same(
120122
"new DateTime('2016-06-22 20:52:43.123400', new DateTimeZone('Europe/Prague'))",
121-
Dumper::dump(new DateTime('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
123+
$dumper->dump(new DateTime('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
122124
);
123125
Assert::same(
124126
"new DateTimeImmutable('2016-06-22 20:52:43.123400', new DateTimeZone('Europe/Prague'))",
125-
Dumper::dump(new DateTimeImmutable('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
127+
$dumper->dump(new DateTimeImmutable('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
126128
);
127129
same(
128130
"Nette\\PhpGenerator\\Dumper::createObject('TestDateTime', [
129131
'date' => '2016-06-22 20:52:43.123400',
130132
'timezone_type' => 3,
131133
'timezone' => 'Europe/Prague',
132134
])",
133-
Dumper::dump(new TestDateTime('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
135+
$dumper->dump(new TestDateTime('2016-06-22 20:52:43.1234', new DateTimeZone('Europe/Prague')))
134136
);
135137

136138
Assert::exception(function () {
137-
Dumper::dump(new class {
139+
$dumper = new Dumper;
140+
$dumper->dump(new class {
138141
});
139142
}, Nette\InvalidArgumentException::class, 'Cannot dump anonymous class.');
140143

141144

142145
Assert::exception(function () {
143146
$rec = [];
144147
$rec[] = &$rec;
145-
Dumper::dump($rec);
148+
$dumper = new Dumper;
149+
$dumper->dump($rec);
146150
}, Nette\InvalidArgumentException::class, 'Nesting level too deep or recursive dependency.');
147151

148152

149153
Assert::exception(function () {
150154
$rec = new stdClass;
151155
$rec->x = &$rec;
152-
Dumper::dump($rec);
156+
$dumper = new Dumper;
157+
$dumper->dump($rec);
153158
}, Nette\InvalidArgumentException::class, 'Nesting level too deep or recursive dependency.');

0 commit comments

Comments
 (0)