Skip to content

Commit e577498

Browse files
committed
Allow Class::function(...) and global_function(...) closures in PHP DSL for factories
1 parent 1cdaa51 commit e577498

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/FactoryTrait.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,29 @@ trait FactoryTrait
2222
*
2323
* @return $this
2424
*/
25-
final public function factory(string|array|ReferenceConfigurator|Expression $factory): static
25+
final public function factory(string|array|ReferenceConfigurator|Expression|\Closure $factory): static
2626
{
27+
if ($factory instanceof \Closure) {
28+
$function = new \ReflectionFunction($factory);
29+
if ($function->isAnonymous()) {
30+
throw new InvalidArgumentException(\sprintf('The closure "%s" passed as factory cannot be an anonymous function.', $function->getName()));
31+
}
32+
33+
if ($function->getClosureThis()) {
34+
throw new InvalidArgumentException(\sprintf('The closure "%s" passed as factory cannot be a bound closure.', $function->getName()));
35+
}
36+
37+
if (null === $class = $function->getClosureScopeClass()) {
38+
// Convert global_function(...) closure into 'global_function'
39+
$this->definition->setFactory($function->getName());
40+
} else {
41+
// Convert Class::method(...) closure into [Class::class, 'method']
42+
$this->definition->setFactory([$class->getName(), $function->getName()]);
43+
}
44+
45+
return $this;
46+
}
47+
2748
if (\is_string($factory) && 1 === substr_count($factory, ':')) {
2849
$factoryParts = explode(':', $factory);
2950

src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
->tag('foo', ['foo' => 'foo'])
2424
->tag('foo', ['bar' => 'bar', 'baz' => 'baz'])
2525
->tag('foo', ['name' => 'bar', 'baz' => 'baz'])
26-
->factory([FooClass::class, 'getInstance'])
26+
->factory(FooClass::getInstance(...))
2727
->property('foo', 'bar')
2828
->property('moo', service('foo.baz'))
2929
->property('qux', ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%'])

0 commit comments

Comments
 (0)