Skip to content

Commit ca69a18

Browse files
[HttpKernel] Fix extracting controller name from closures
1 parent b3347b3 commit ca69a18

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

ControllerMetadata/ArgumentMetadataFactory.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@ public function createArgumentMetadata($controller): array
2727

2828
if (\is_array($controller)) {
2929
$reflection = new \ReflectionMethod($controller[0], $controller[1]);
30+
$class = $reflection->class;
3031
} elseif (\is_object($controller) && !$controller instanceof \Closure) {
31-
$reflection = (new \ReflectionObject($controller))->getMethod('__invoke');
32+
$reflection = new \ReflectionMethod($controller, '__invoke');
33+
$class = $reflection->class;
3234
} else {
3335
$reflection = new \ReflectionFunction($controller);
36+
if ($class = str_contains($reflection->name, '{closure}') ? null : $reflection->getClosureScopeClass()) {
37+
$class = $class->name;
38+
}
3439
}
3540

3641
foreach ($reflection->getParameters() as $param) {
37-
$arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param, $reflection), $param->isVariadic(), $param->isDefaultValueAvailable(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->allowsNull());
42+
$arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param, $reflection, $class), $param->isVariadic(), $param->isDefaultValueAvailable(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, $param->allowsNull());
3843
}
3944

4045
return $arguments;
@@ -43,20 +48,19 @@ public function createArgumentMetadata($controller): array
4348
/**
4449
* Returns an associated type to the given parameter if available.
4550
*/
46-
private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function): ?string
51+
private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function, ?string $class): ?string
4752
{
4853
if (!$type = $parameter->getType()) {
4954
return null;
5055
}
5156
$name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
5257

53-
if ($function instanceof \ReflectionMethod) {
54-
$lcName = strtolower($name);
55-
switch ($lcName) {
58+
if (null !== $class) {
59+
switch (strtolower($name)) {
5660
case 'self':
57-
return $function->getDeclaringClass()->name;
61+
return $class;
5862
case 'parent':
59-
return ($parent = $function->getDeclaringClass()->getParentClass()) ? $parent->name : null;
63+
return get_parent_class($class) ?: null;
6064
}
6165
}
6266

Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ public function testBasicTypesSignature()
105105
], $arguments);
106106
}
107107

108+
public function testNamedClosure()
109+
{
110+
$arguments = $this->factory->createArgumentMetadata(\Closure::fromCallable([$this, 'signature1']));
111+
112+
$this->assertEquals([
113+
new ArgumentMetadata('foo', self::class, false, false, null),
114+
new ArgumentMetadata('bar', 'array', false, false, null),
115+
new ArgumentMetadata('baz', 'callable', false, false, null),
116+
], $arguments);
117+
}
118+
108119
public function testNullableTypesSignature()
109120
{
110121
$arguments = $this->factory->createArgumentMetadata([new NullableController(), 'action']);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy