Skip to content

Commit 01cb93f

Browse files
bug #29054 [VarDumper] fix dump of closures created from callables (nicolas-grekas)
This PR was merged into the 3.4 branch. Discussion ---------- [VarDumper] fix dump of closures created from callables | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - We are missing displaying full information about closures created using `ReflectionMethod::getClosure()` or `Closure::fromCallable()`. This PR fixes it. For VarDumper but also other places where we have logic to display them. Commits ------- 1c1818b876 [VarDumper] fix dump of closures created from callables
2 parents 3562829 + ba8e63d commit 01cb93f

File tree

7 files changed

+58
-10
lines changed

7 files changed

+58
-10
lines changed

Console/Descriptor/JsonDescriptor.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,20 @@ private function getCallableData($callable, array $options = array())
368368
if ($callable instanceof \Closure) {
369369
$data['type'] = 'closure';
370370

371+
$r = new \ReflectionFunction($callable);
372+
if (false !== strpos($r->name, '{closure}')) {
373+
return $data;
374+
}
375+
$data['name'] = $r->name;
376+
377+
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
378+
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
379+
$data['class'] = $scopeClass;
380+
if (!$class) {
381+
$data['static'] = true;
382+
}
383+
}
384+
371385
return $data;
372386
}
373387

Console/Descriptor/MarkdownDescriptor.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,20 @@ protected function describeCallable($callable, array $options = array())
354354
if ($callable instanceof \Closure) {
355355
$string .= "\n- Type: `closure`";
356356

357+
$r = new \ReflectionFunction($callable);
358+
if (false !== strpos($r->name, '{closure}')) {
359+
return $this->write($string."\n");
360+
}
361+
$string .= "\n".sprintf('- Name: `%s`', $r->name);
362+
363+
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
364+
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
365+
$string .= "\n".sprintf('- Class: `%s`', $class);
366+
if (!$class) {
367+
$string .= "\n- Static: yes";
368+
}
369+
}
370+
357371
return $this->write($string."\n");
358372
}
359373

Console/Descriptor/TextDescriptor.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,7 @@ protected function describeRouteCollection(RouteCollection $routes, array $optio
5656

5757
if ($showControllers) {
5858
$controller = $route->getDefault('_controller');
59-
if ($controller instanceof \Closure) {
60-
$controller = 'Closure';
61-
} elseif (\is_object($controller)) {
62-
$controller = \get_class($controller);
63-
}
64-
$row[] = $controller;
59+
$row[] = $this->formatCallable($controller);
6560
}
6661

6762
$tableRows[] = $row;
@@ -474,7 +469,18 @@ private function formatCallable($callable)
474469
}
475470

476471
if ($callable instanceof \Closure) {
477-
return '\Closure()';
472+
$r = new \ReflectionFunction($callable);
473+
if (false !== strpos($r->name, '{closure}')) {
474+
return 'Closure()';
475+
}
476+
if ($class = $r->getClosureScopeClass()) {
477+
return sprintf('%s::%s()', $class, $r->name);
478+
}
479+
if ($class = $r->getClosureThis()) {
480+
return sprintf('%s::%s()', \get_class($class), $r->name);
481+
}
482+
483+
return $r->name.'()';
478484
}
479485

480486
if (method_exists($callable, '__invoke')) {

Console/Descriptor/XmlDescriptor.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,20 @@ private function getCallableDocument($callable)
580580
if ($callable instanceof \Closure) {
581581
$callableXML->setAttribute('type', 'closure');
582582

583+
$r = new \ReflectionFunction($callable);
584+
if (false !== strpos($r->name, '{closure}')) {
585+
return $dom;
586+
}
587+
$callableXML->setAttribute('name', $r->name);
588+
589+
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
590+
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
591+
$callableXML->setAttribute('class', $class);
592+
if (!$class) {
593+
$callableXML->setAttribute('static', 'true');
594+
}
595+
}
596+
583597
return $dom;
584598
}
585599

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
\Closure()
1+
Closure()

Tests/Fixtures/Descriptor/event_dispatcher_1_event1.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
 Order   Callable   Priority 
77
------- ------------------- ----------
88
#1 global_function() 255
9-
#2 \Closure() -1
9+
#2 Closure() -1
1010
------- ------------------- ----------
1111

Tests/Fixtures/Descriptor/event_dispatcher_1_events.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
 Order   Callable   Priority 
1010
------- ------------------- ----------
1111
#1 global_function() 255
12-
#2 \Closure() -1
12+
#2 Closure() -1
1313
------- ------------------- ----------
1414

1515
"event2" event

0 commit comments

Comments
 (0)