diff --git a/UPGRADE-3.2.md b/UPGRADE-3.2.md index e151275472..8a14f2d4b6 100644 --- a/UPGRADE-3.2.md +++ b/UPGRADE-3.2.md @@ -64,6 +64,15 @@ DependencyInjection * Calling `get()` on a `ContainerBuilder` instance before compiling the container is deprecated and will throw an exception in Symfony 4.0. + * Setting or unsetting a private service with the `Container::set()` method is + deprecated. Only public services can be set or unset in Symfony 4.0. + + * Checking the existence of a private service with the `Container::has()` + method is deprecated and will return `false` in Symfony 4.0. + + * Requesting a private service with the `Container::get()` method is deprecated + and will no longer be supported in Symfony 4.0. + ExpressionLanguage ------------------- diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php index b5a9b53e5d..28dbb976d3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php @@ -27,10 +27,13 @@ class WebProfilerExtensionTest extends TestCase */ private $container; - public static function assertSaneContainer(Container $container, $message = '') + public static function assertSaneContainer(Container $container, $message = '', $knownPrivates = array()) { $errors = array(); foreach ($container->getServiceIds() as $id) { + if (in_array($id, $knownPrivates, true)) { // to be removed in 4.0 + continue; + } try { $container->get($id); } catch (\Exception $e) { @@ -98,7 +101,7 @@ class WebProfilerExtensionTest extends TestCase $this->assertSame($listenerInjected, $this->container->has('web_profiler.debug_toolbar')); - $this->assertSaneContainer($this->getDumpedContainer()); + $this->assertSaneContainer($this->getDumpedContainer(), '', array('web_profiler.csp.handler')); if ($listenerInjected) { $this->assertSame($listenerEnabled, $this->container->get('web_profiler.debug_toolbar')->isEnabled()); diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index da84d18acf..119fb432a3 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -200,6 +200,10 @@ class Container implements ResettableContainerInterface public function has($id) { for ($i = 2;;) { + if (isset($this->privates[$id])) { + @trigger_error(sprintf('Checking for the existence of the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); + } + if ('service_container' === $id || isset($this->aliases[$id]) || isset($this->services[$id]) @@ -207,10 +211,6 @@ class Container implements ResettableContainerInterface return true; } - if (isset($this->privates[$id])) { - @trigger_error(sprintf('Checking for the existence of the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); - } - if (isset($this->methodMap[$id])) { return true; } @@ -262,6 +262,10 @@ class Container implements ResettableContainerInterface if (isset($this->aliases[$id])) { $id = $this->aliases[$id]; } + if (isset($this->privates[$id])) { + @trigger_error(sprintf('Requesting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); + } + // Re-use shared service instance if it exists. if (isset($this->services[$id])) { return $this->services[$id]; @@ -300,9 +304,6 @@ class Container implements ResettableContainerInterface return; } - if (isset($this->privates[$id])) { - @trigger_error(sprintf('Requesting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); - } $this->loading[$id] = true; diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index b2a1d77a6d..b788de5a7b 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -573,9 +573,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface $compiler->compile($this); foreach ($this->definitions as $id => $definition) { - if (!$definition->isPublic()) { - $this->privates[$id] = true; - } if ($this->trackResources && $definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) { $this->addClassResource(new \ReflectionClass($class)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index 30173f7a18..8d5eda9ce5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -126,7 +126,7 @@ class ContainerTest extends TestCase $sc = new ProjectServiceContainer(); $sc->set('foo', $obj = new \stdClass()); - $this->assertEquals(array('service_container', 'internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by factory methods in the method map, followed by service ids defined by set()'); + $this->assertEquals(array('service_container', 'internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'internal_dependency', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by factory methods in the method map, followed by service ids defined by set()'); } /** @@ -397,7 +397,8 @@ class ContainerTest extends TestCase public function testChangeInternalPrivateServiceIsDeprecated() { $c = new ProjectServiceContainer(); - $c->set('internal', new \stdClass()); + $c->set('internal', $internal = new \stdClass()); + $this->assertSame($c->get('internal'), $internal); } /** @@ -407,7 +408,8 @@ class ContainerTest extends TestCase public function testCheckExistenceOfAnInternalPrivateServiceIsDeprecated() { $c = new ProjectServiceContainer(); - $c->has('internal'); + $c->get('internal_dependency'); + $this->assertTrue($c->has('internal')); } /** @@ -417,6 +419,7 @@ class ContainerTest extends TestCase public function testRequestAnInternalSharedPrivateServiceIsDeprecated() { $c = new ProjectServiceContainer(); + $c->get('internal_dependency'); $c->get('internal'); } } @@ -435,6 +438,7 @@ class ProjectServiceContainer extends Container 'circular' => 'getCircularService', 'throw_exception' => 'getThrowExceptionService', 'throws_exception_on_service_configuration' => 'getThrowsExceptionOnServiceConfigurationService', + 'internal_dependency' => 'getInternalDependencyService', ); public function __construct() @@ -451,7 +455,7 @@ class ProjectServiceContainer extends Container protected function getInternalService() { - return $this->__internal; + return $this->services['internal'] = $this->__internal; } protected function getBarService() @@ -485,6 +489,15 @@ class ProjectServiceContainer extends Container throw new \Exception('Something was terribly wrong while trying to configure the service!'); } + + protected function getInternalDependencyService() + { + $this->services['internal_dependency'] = $instance = new \stdClass(); + + $instance->internal = isset($this->services['internal']) ? $this->services['internal'] : $this->getInternalService(); + + return $instance; + } } class LegacyProjectServiceContainer extends Container