minor #18682 [DependencyInjection] Avoid generating call_user_func in more cases (realityking)

This PR was submitted for the master branch but it was merged into the 3.0 branch instead (closes #18682).

Discussion
----------

[DependencyInjection] Avoid generating call_user_func in more cases

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

This is a follow up to #9807 to add the PHP 5.4 only coded I excluded when I split it off #9432.

Commits
-------

2718a6c [DependencyInjection] Avoid generating call_user_func in more cases
This commit is contained in:
Nicolas Grekas 2016-05-19 10:07:44 +02:00
commit 7bdd50cae6
8 changed files with 157 additions and 1 deletions

View File

@ -537,6 +537,10 @@ class PhpDumper extends Dumper
return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName);
}
if (0 === strpos($class, 'new ')) {
return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}
return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}
@ -713,6 +717,10 @@ EOF;
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
}
if (0 === strpos($class, 'new ')) {
return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
}
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
}

View File

@ -78,6 +78,15 @@ $container
->register('configured_service', 'stdClass')
->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
;
$container
->register('configurator_service_simple', 'ConfClass')
->addArgument('bar')
->setPublic(false)
;
$container
->register('configured_service_simple', 'stdClass')
->setConfigurator(array(new Reference('configurator_service_simple'), 'configureStdClass'))
;
$container
->register('decorated', 'stdClass')
;
@ -111,5 +120,14 @@ $container
->register('service_from_static_method', 'Bar\FooClass')
->setFactory(array('Bar\FooClass', 'getInstance'))
;
$container
->register('factory_simple', 'SimpleFactoryClass')
->addArgument('foo')
->setPublic(false)
;
$container
->register('factory_service_simple', 'Bar')
->setFactory(array(new Reference('factory_simple'), 'getInstance'))
;
return $container;

View File

@ -14,6 +14,8 @@ digraph sc {
node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configurator_service_simple [label="configurator_service_simple\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configured_service_simple [label="configured_service_simple\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
@ -22,6 +24,8 @@ digraph sc {
node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];

View File

@ -40,7 +40,7 @@ class ProjectServiceContainer extends Container
*/
protected function getServiceFromAnonymousFactoryService()
{
return $this->services['service_from_anonymous_factory'] = call_user_func(array(new \Bar\FooClass(), 'getInstance'));
return $this->services['service_from_anonymous_factory'] = (new \Bar\FooClass())->getInstance();
}
/**

View File

@ -28,12 +28,16 @@ class ProjectServiceContainer extends Container
'bar' => 'getBarService',
'baz' => 'getBazService',
'configurator_service' => 'getConfiguratorServiceService',
'configurator_service_simple' => 'getConfiguratorServiceSimpleService',
'configured_service' => 'getConfiguredServiceService',
'configured_service_simple' => 'getConfiguredServiceSimpleService',
'decorated' => 'getDecoratedService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
'factory_service_simple' => 'getFactoryServiceSimpleService',
'factory_simple' => 'getFactorySimpleService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
@ -104,6 +108,23 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the 'configured_service_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance.
*/
protected function getConfiguredServiceSimpleService()
{
$this->services['configured_service_simple'] = $instance = new \stdClass();
$this->get('configurator_service_simple')->configureStdClass($instance);
return $instance;
}
/**
* Gets the 'decorated' service.
*
@ -173,6 +194,19 @@ class ProjectServiceContainer extends Container
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}
/**
* Gets the 'factory_service_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \Bar A Bar instance.
*/
protected function getFactoryServiceSimpleService()
{
return $this->services['factory_service_simple'] = $this->get('factory_simple')->getInstance();
}
/**
* Gets the 'foo' service.
*
@ -334,6 +368,40 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the 'configurator_service_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* This service is private.
* If you want to be able to request this service from the container directly,
* make it public, otherwise you might end up with broken code.
*
* @return \ConfClass A ConfClass instance.
*/
protected function getConfiguratorServiceSimpleService()
{
return $this->services['configurator_service_simple'] = new \ConfClass('bar');
}
/**
* Gets the 'factory_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* This service is private.
* If you want to be able to request this service from the container directly,
* make it public, otherwise you might end up with broken code.
*
* @return \SimpleFactoryClass A SimpleFactoryClass instance.
*/
protected function getFactorySimpleService()
{
return $this->services['factory_simple'] = new \SimpleFactoryClass('foo');
}
/**
* Gets the 'inlined' service.
*

View File

@ -30,10 +30,12 @@ class ProjectServiceContainer extends Container
'bar' => 'getBarService',
'baz' => 'getBazService',
'configured_service' => 'getConfiguredServiceService',
'configured_service_simple' => 'getConfiguredServiceSimpleService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
'factory_service_simple' => 'getFactoryServiceSimpleService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
@ -114,6 +116,23 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the 'configured_service_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance.
*/
protected function getConfiguredServiceSimpleService()
{
$this->services['configured_service_simple'] = $instance = new \stdClass();
(new \ConfClass('bar'))->configureStdClass($instance);
return $instance;
}
/**
* Gets the 'decorator_service' service.
*
@ -170,6 +189,19 @@ class ProjectServiceContainer extends Container
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}
/**
* Gets the 'factory_service_simple' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \Bar A Bar instance.
*/
protected function getFactoryServiceSimpleService()
{
return $this->services['factory_service_simple'] = (new \SimpleFactoryClass('foo'))->getInstance();
}
/**
* Gets the 'foo' service.
*

View File

@ -84,6 +84,12 @@
<service id="configured_service" class="stdClass">
<configurator service="configurator_service" method="configureStdClass"/>
</service>
<service id="configurator_service_simple" class="ConfClass" public="false">
<argument>bar</argument>
</service>
<service id="configured_service_simple" class="stdClass">
<configurator service="configurator_service_simple" method="configureStdClass"/>
</service>
<service id="decorated" class="stdClass"/>
<service id="decorator_service" class="stdClass" decorates="decorated"/>
<service id="decorator_service_with_name" class="stdClass" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
@ -103,6 +109,12 @@
<service id="service_from_static_method" class="Bar\FooClass">
<factory class="Bar\FooClass" method="getInstance"/>
</service>
<service id="factory_simple" class="SimpleFactoryClass" public="false">
<argument>foo</argument>
</service>
<service id="factory_service_simple" class="Bar">
<factory service="factory_simple" method="getInstance"/>
</service>
<service id="alias_for_foo" alias="foo"/>
<service id="alias_for_alias" alias="foo"/>
</services>

View File

@ -67,6 +67,13 @@ services:
configured_service:
class: stdClass
configurator: ['@configurator_service', configureStdClass]
configurator_service_simple:
class: ConfClass
public: false
arguments: ['bar']
configured_service_simple:
class: stdClass
configurator: ['@configurator_service_simple', configureStdClass]
decorated:
class: stdClass
decorator_service:
@ -93,5 +100,12 @@ services:
service_from_static_method:
class: Bar\FooClass
factory: [Bar\FooClass, getInstance]
factory_simple:
class: SimpleFactoryClass
public: false
arguments: ['foo']
factory_service_simple:
class: Bar
factory: ['@factory_simple', getInstance]
alias_for_foo: '@foo'
alias_for_alias: '@foo'