-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[DependencyInjection] Update ResolveClassPass to check class existence
#61215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckServiceClassExistsPassTest.php
Outdated
Show resolved
Hide resolved
740f29a to
65259c9
Compare
src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassExistsPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassExistsPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassExistsPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassExistsPass.php
Outdated
Show resolved
Hide resolved
This comment was marked as outdated.
This comment was marked as outdated.
But then it would not work if you define a manual id and make a typo in the class (although more of a niche case) |
So we could have something like |
65259c9 to
321ccff
Compare
|
There are many ways one can mess up with their DI config. Validating everything adds to the compilation time. That's something we always considered outside of the scope of the compilation step. |
ResolveClassPass to check class existence
nicolas-grekas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, test cases changes look consistent with the updated behavior.
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/fixture_app_services.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php
Outdated
Show resolved
Hide resolved
9690e1e to
349c87c
Compare
349c87c to
dbd5c25
Compare
|
Thank you @GaryPEGEOT. |
…without a class when its id is a non-existing FQCN (nicolas-grekas) This PR was merged into the 7.4 branch. Discussion ---------- [DependencyInjection] Deprecate registering a service without a class when its id is a non-existing FQCN | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT #61215 might be too disruptive. This turns the exception into a deprecation. Commits ------- 7d3ad74 [DependencyInjection] Deprecate registering a service without a class when its id is a non-existing FQCN
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not see the deprecation, but a fatal error instead. TODO: * Add tests * Add an issue (see https://forge.typo3.org/issues/108349 for reference)
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91943 Tested-by: Benjamin Franzke <ben@bnf.dev> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: Moritz Ngo <moritz.ngo@kandoh.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Moritz Ngo <moritz.ngo@kandoh.de>
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91941 Tested-by: Moritz Ngo <moritz.ngo@kandoh.de> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Moritz Ngo <moritz.ngo@kandoh.de> Tested-by: Benjamin Franzke <ben@bnf.dev>
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91926 Tested-by: Achim Fritz <af@achimfritz.de> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: core-ci <typo3@b13.com> Tested-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Stephan Großberndt <stephan.grossberndt@typo3.org> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Benjamin Franzke <ben@bnf.dev>
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91943 Tested-by: Benjamin Franzke <ben@bnf.dev> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: Moritz Ngo <moritz.ngo@kandoh.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Moritz Ngo <moritz.ngo@kandoh.de>
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91941 Tested-by: Moritz Ngo <moritz.ngo@kandoh.de> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Moritz Ngo <moritz.ngo@kandoh.de> Tested-by: Benjamin Franzke <ben@bnf.dev>
Symfony DI added [1] a non-optional `class_exists()` check in `Symfony\Component\DependencyInjection\Compiler\ResolveClassPass` for the versions >=7.4 (including 8.0), which is no longer guarded by a previous `$definition instanceof ChildDefinition` condition. This causes PHP errors when classes are (tried to be) autoloaded, that implement interfaces which are not available (because they use them as an optional dependency, like optional EXT:reports integration). The change was initially implemented as a breaking change, but was intended to be lifted to be only a deprecation later [2]. This relaxation works for classes that are not available at all, but not for classes that are available from a autoloader perspective, but whose static dependencies are not and are therefore not loadable. As a solution we revert to the old class resolution algorithm from v7.3 and enqueue this overwrite for the upstream class resolution compiler pass, which makes the upstream compiler pass a no-op. An upstream fix is hopefully added later on via: symfony/symfony#62544 [1] symfony/symfony#61215 [2] symfony/symfony#62544 Releases: main, 13.4, 12.4 Resolves: #108349 Change-Id: I5d55bfdc21caf4aece95f662e21918dd3494ad58 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/91926 Tested-by: Achim Fritz <af@achimfritz.de> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Tested-by: core-ci <typo3@b13.com> Tested-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Stephan Großberndt <stephan.grossberndt@typo3.org> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Benjamin Franzke <ben@bnf.dev>
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
… PHP error The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with symfony#61215 in order to produce an error if a service is not available. This error was later relaxed to a deprecation in symfony#61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not receive the deprecation, but a fatal error instead.
…t trigger a PHP error (bnf) This PR was merged into the 7.4 branch. Discussion ---------- [DependencyInjection] Ensure deprecation detection does not trigger a PHP error `Exception Interface "TYPO3\CMS\Reports\StatusProviderInterface" not found` See https://forge.typo3.org/issues/108349 | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #62589 | License | MIT The `class_exists` check and the condition `$definition instanceof ChildDefinition` have been swapped with #61215 in order to produce an error if a service is not available. This error was later relaxed in #61270, but the executing order of the condition kept to be `class_exists` first, then `instanceof`. That means, if `class_exists` fails with a PHP error (like PHP Fatal Error: Interface "My\Vendor\MyInterface" not found`) affected uses will not see the deprecation, but a fatal error instead. Commits ------- 662d28f [DependencyInjection] Ensure deprecation detection does not trigger a PHP error
Currently doesn't check for incorrect factories, but I'm not sure what would be the best approach