Symfony version(s) affected: 3.4.47 & 4.4.19 & 5.2.3
phpdocumenter/reflection-docblock is an optional dependency of
symfony/property-info, but a required dependency when the
PhpDocExtractor is used. If someone wants to use the
PhpDocExtractor and did not install
phpdocumenter/reflection-docblock, then a clear exception is shown:
Unable to use the "PhpDocExtractor" class as the "phpdocumentor/reflection-docblock" package is not installed.
So far, so good. Install the dependency and continue.
The problemen arises when
phpdocumentor/reflection-docblock is already installed as a require-dev dependency, which is probably true in many projects:
phpdocumentor/reflection-docblock is a dependency of
phpunit/phpunit. In those cases, you don’t get the exception and things work fine while developing and testing. However, after deploying the application to production, it breaks. Require-dev dependencies are not installed, and therefore
phpdocumentor/reflection-docblock is not installed, and thus the exception is only shown in production.
I think this is a big risk. There is no automated way to test this kind of things, because automated test tools also usually run with development dependencies. The underlying problem is that in composer, dev en production dependencies are mixed. Therefore, production code can (accidentally) depend on dev-dependencies.
This is of course a problem with all optional dependencies that could break the application when not present. But this use case is probably more common than others, and therefore a bigger risk.
How to reproduce
Create a project with
symfony/property-info as dependency and
phpunit/phpunit as dev-dependency and make use of the
PhpDocExtractor. This works, until installling the application without dev-dependencies.
The ultimate solution is to not rely on optional dependencies, because they could be available during development, but not in production. Instead, either require the dependency or extract the piece of code that requires the dependency to a separate composer package.