Skip to content

Commit

Permalink
bug #25160 [DI] Prevent a ReflectionException during cache:clear when…
Browse files Browse the repository at this point in the history
… the parent class doesn't exist (dunglas)

This PR was squashed before being merged into the 3.4 branch (closes #25160).

Discussion
----------

[DI] Prevent a ReflectionException during cache:clear when the parent class doesn't exist

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  |  no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Currently, if you just run the following commands:

```
composer create-project -s beta symfony/skeleton:^3.4 test
composer req orm
```

You get the following error:

```
In UniqueEntityValidator.php line 27:

  [ReflectionException]
  Class Symfony\Component\Validator\ConstraintValidator not found
```

`UniqueEntityValidator` is in the bridge, but it's parent class is in the validator (that is not installed by default). The hot path optimization feature (enabled by default) uses reflection, and the reflection API throws an exception in this specific case.

This PR fixes the error.

Commits
-------

6e622c6 [DI] Prevent a ReflectionException during cache:clear when the parent class doesn't exist
  • Loading branch information
nicolas-grekas committed Nov 27, 2017
2 parents d954af5 + 6e622c6 commit a19d1e5
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
Expand Up @@ -378,7 +378,7 @@ private function collectLineage($class, array &$lineage)
if (isset($lineage[$class])) {
return;
}
if (!$r = $this->container->getReflectionClass($class)) {
if (!$r = $this->container->getReflectionClass($class, false)) {
return;
}
if ($this->container instanceof $class) {
Expand Down
@@ -0,0 +1,7 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

class ParentNotExists extends \NotExists
{
}
Expand Up @@ -7,11 +7,13 @@
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath;
use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists;

$container = new ContainerBuilder();

$container->register(HotPath\C1::class)->addTag('container.hot_path')->setPublic(true);
$container->register(HotPath\C2::class)->addArgument(new Reference(HotPath\C3::class))->setPublic(true);
$container->register(HotPath\C3::class);
$container->register(ParentNotExists::class)->setPublic(true);

return $container;
Expand Up @@ -32,8 +32,10 @@ public function __construct()
'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c1' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1',
'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c2' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2',
'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c3' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3',
'symfony\\component\\dependencyinjection\\tests\\fixtures\\parentnotexists' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists',
);
$this->methodMap = array(
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists' => 'getParentNotExistsService',
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1' => 'getC1Service',
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2' => 'getC2Service',
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3' => 'getC3Service',
Expand Down Expand Up @@ -75,6 +77,16 @@ public function isFrozen()
return true;
}

/**
* Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists' shared service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists
*/
protected function getParentNotExistsService()
{
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists();
}

/**
* Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1' shared service.
*
Expand Down

0 comments on commit a19d1e5

Please sign in to comment.