diff --git a/UPGRADE-4.4.md b/UPGRADE-4.4.md index ac716a4b07394..584eb693e2ab5 100644 --- a/UPGRADE-4.4.md +++ b/UPGRADE-4.4.md @@ -60,7 +60,7 @@ DependencyInjection ```php new Definition('%my_class%'); ``` - + DoctrineBridge -------------- * Deprecated injecting `ClassMetadataFactory` in `DoctrineExtractor`, an instance of `EntityManagerInterface` should be @@ -96,7 +96,7 @@ FrameworkBundle * Deprecated `routing.loader.service`, use `routing.loader.container` instead. * Not tagging service route loaders with `routing.route_loader` has been deprecated. * Overriding the methods `KernelTestCase::tearDown()` and `WebTestCase::tearDown()` without the `void` return-type is deprecated. - + HttpClient ---------- @@ -139,7 +139,7 @@ HttpKernel } ``` - As many bundles must be compatible with a range of Symfony versions, the current + As many bundles must be compatible with a range of Symfony versions, the current directory convention is not deprecated yet, but it will be in the future. * Deprecated the second and third argument of `KernelInterface::locateResource` @@ -148,6 +148,7 @@ HttpKernel fallback directories. Resources like service definitions are usually loaded relative to the current directory or with a glob pattern. The fallback directories have never been advocated so you likely do not use those in any app based on the SF Standard or Flex edition. + * Getting the container from a non-booted kernel is deprecated Lock ---- @@ -171,7 +172,7 @@ MonologBridge -------------- * The `RouteProcessor` has been marked final. - + Process ------- @@ -195,14 +196,14 @@ Security * Implementations of `PasswordEncoderInterface` and `UserPasswordEncoderInterface` should add a new `needsRehash()` method * Deprecated returning a non-boolean value when implementing `Guard\AuthenticatorInterface::checkCredentials()`. Please explicitly return `false` to indicate invalid credentials. * Deprecated passing more than one attribute to `AccessDecisionManager::decide()` and `AuthorizationChecker::isGranted()` (and indirectly the `is_granted()` Twig and ExpressionLanguage function) - + **Before** ```php if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) { // ... } ``` - + **After** ```php if ($this->authorizationChecker->isGranted(new Expression("has_role('ROLE_USER') or has_role('ROLE_ADMIN')"))) {} @@ -230,18 +231,18 @@ TwigBridge * Deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the `DebugCommand::__construct()` method, swap the variables position. * Deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit. - + TwigBundle ---------- * Deprecated `twig.exception_controller` configuration option, set it to "null" and use `framework.error_controller` instead: - + Before: ```yaml twig: exception_controller: 'App\Controller\MyExceptionController' ``` - + After: ```yaml twig: @@ -250,36 +251,36 @@ TwigBundle framework: error_controller: 'App\Controller\MyExceptionController' ``` - - The new default exception controller will also change the error response content according to + + The new default exception controller will also change the error response content according to https://tools.ietf.org/html/rfc7807 for `json`, `xml`, `atom` and `txt` formats: - + Before: ```json - { - "error": { - "code": 404, - "message": "Sorry, the page you are looking for could not be found" - } + { + "error": { + "code": 404, + "message": "Sorry, the page you are looking for could not be found" + } } ``` - + After: ```json - { + { "title": "Not Found", - "status": 404, + "status": 404, "detail": "Sorry, the page you are looking for could not be found" } ``` - + * Deprecated the `ExceptionController` and `PreviewErrorController` controllers, use `ErrorController` from the HttpKernel component instead * Deprecated all built-in error templates, use the error renderer mechanism of the `ErrorRenderer` component - * Deprecated loading custom error templates in non-html formats. Custom HTML error pages based on Twig keep working as before: + * Deprecated loading custom error templates in non-html formats. Custom HTML error pages based on Twig keep working as before: Before (`templates/bundles/TwigBundle/Exception/error.jsonld.twig`): ```twig - { + { "@id": "https://example.com", "@type": "error", "@context": { @@ -289,7 +290,7 @@ TwigBundle } } ``` - + After (`App\ErrorRenderer\JsonLdErrorRenderer`): ```php class JsonLdErrorRenderer implements ErrorRendererInterface @@ -298,7 +299,7 @@ TwigBundle { return 'jsonld'; } - + public function render(FlattenException $exception): string { return json_encode([ @@ -323,7 +324,7 @@ Validator * Deprecated using anything else than a `string` as the code of a `ConstraintViolation`, a `string` type-hint will be added to the constructor of the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` method in 5.0. - * Deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. + * Deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. Pass it as the first argument instead. * The `Length` constraint expects the `allowEmptyString` option to be defined when the `min` option is used. @@ -343,7 +344,7 @@ WebServerBundle --------------- * The bundle is deprecated and will be removed in 5.0. - + Yaml ---- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 12a34a85d35da..1039e3a5fe036 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -288,6 +288,7 @@ HttpFoundation use `Symfony\Component\Mime\FileinfoMimeTypeGuesser` instead. * `ApacheRequest` has been removed, use the `Request` class instead. * The third argument of the `HeaderBag::get()` method has been removed, use method `all()` instead. + * Getting the container from a non-booted kernel is not possible anymore. HttpKernel ---------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index 02806ad6a98c8..8d0bc21ef556b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -127,11 +127,15 @@ protected static function createKernel(array $options = []) protected static function ensureKernelShutdown() { if (null !== static::$kernel) { - $container = static::$kernel->getContainer(); - static::$kernel->shutdown(); - static::$booted = false; - if ($container instanceof ResetInterface) { - $container->reset(); + $isBooted = (new \ReflectionClass(static::$kernel))->getProperty('booted'); + $isBooted->setAccessible(true); + if ($isBooted->getValue(static::$kernel)) { + $container = static::$kernel->getContainer(); + static::$kernel->shutdown(); + static::$booted = false; + if ($container instanceof ResetInterface) { + $container->reset(); + } } } static::$container = null; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php index 0d329582b39ef..14cdef6285981 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php @@ -14,6 +14,7 @@ use Psr\Log\NullLogger; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpKernel\Kernel; @@ -96,4 +97,13 @@ protected function getKernelParameters(): array return $parameters; } + + public function getContainer(): ContainerInterface + { + if (!$this->booted) { + throw new \LogicException('Cannot access the container on a non-booted kernel. Did you forget to boot it?'); + } + + return parent::getContainer(); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php index 8e622282c2c1d..ca6f16c0d6ae5 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional\app; use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpKernel\Kernel; @@ -98,4 +99,13 @@ protected function getKernelParameters(): array return $parameters; } + + public function getContainer(): ContainerInterface + { + if (!$this->booted) { + throw new \LogicException('Cannot access the container on a non-booted kernel. Did you forget to boot it?'); + } + + return parent::getContainer(); + } } diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 5eb335ac309f2..6a11a170b3101 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -14,6 +14,7 @@ CHANGELOG so you likely do not use those in any app based on the SF Standard or Flex edition. * Marked all dispatched event classes as `@final` * Added `ErrorController` to enable the preview and error rendering mechanism + * Getting the container from a non-booted kernel is deprecated. 4.3.0 ----- diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 0f4be74092a7e..eeed399b0d5fd 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -380,6 +380,10 @@ public function getProjectDir() */ public function getContainer() { + if (!$this->booted) { + @trigger_error('Getting the container from a non-booted kernel is deprecated since Symfony 4.4.', E_USER_DEPRECATED); + } + return $this->container; } diff --git a/src/Symfony/Component/HttpKernel/KernelInterface.php b/src/Symfony/Component/HttpKernel/KernelInterface.php index c97dde8292718..00a1aec817e35 100644 --- a/src/Symfony/Component/HttpKernel/KernelInterface.php +++ b/src/Symfony/Component/HttpKernel/KernelInterface.php @@ -124,7 +124,7 @@ public function getRootDir(); /** * Gets the current container. * - * @return ContainerInterface|null A ContainerInterface instance or null when the Kernel is shutdown + * @return ContainerInterface */ public function getContainer(); diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 065a3ea148276..1f6811639b94c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -46,6 +46,17 @@ public function testConstructor() $this->assertEquals($debug, $kernel->isDebug()); $this->assertFalse($kernel->isBooted()); $this->assertLessThanOrEqual(microtime(true), $kernel->getStartTime()); + } + + /** + * @group legacy + * @expectedDeprecation Getting the container from a non-booted kernel is deprecated since Symfony 4.4. + */ + public function testGetContainerForANonBootedKernel() + { + $kernel = new KernelForTest('test_env', true); + + $this->assertFalse($kernel->isBooted()); $this->assertNull($kernel->getContainer()); } @@ -61,7 +72,6 @@ public function testClone() $this->assertEquals($debug, $clone->isDebug()); $this->assertFalse($clone->isBooted()); $this->assertLessThanOrEqual(microtime(true), $clone->getStartTime()); - $this->assertNull($clone->getContainer()); } public function testClassNameValidityGetter() @@ -486,6 +496,18 @@ public function testTerminateReturnsSilentlyIfKernelIsNotBooted() $kernel->terminate(Request::create('/'), new Response()); } + /** + * @group legacy + * @expectedDeprecation Getting the container from a non-booted kernel is deprecated since Symfony 4.4. + */ + public function testDeprecatedNullKernel() + { + $kernel = $this->getKernel(); + $kernel->shutdown(); + + $this->assertNull($kernel->getContainer()); + } + public function testTerminateDelegatesTerminationOnlyForTerminableInterface() { // does not implement TerminableInterface
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: