merged branch ludekstepan/fix-di-scope-nesting (PR #6119)
This PR was submitted for the master branch but it was merged into the 2.1 branch instead (closes #6119). Commits ------- 3b9f763 [DI] Fix 'undefined index' error, when entering scope recursively Discussion ---------- [DI] Fix 'undefined index' error, when entering scope recursively Imagine two scopes: ```php $container = new Container(); $container->addScope(new Scope('foo')); $container->addScope(new Scope('bar', 'foo')); ``` Enter the same scope twice recursively: ```php $container->enterScope('foo'); // not entering bar in between $container->enterScope('foo'); // prints warning: undefined index: bar // at Symfony/Component/DependencyInjection/Container.php:341 ``` --------------------------------------------------------------------------- by fabpot at 2012-11-28T16:30:00Z The problem exists, but the fix looks wrong to me. We should keep the scoped services even with nested scopes. Right now, and even after your patch, we loose some information. --------------------------------------------------------------------------- by ludekstepan at 2012-11-28T16:38:05Z I don't know how to fix properly, the patch above is just a workaround. Without the patch, it's not possible to simply create a child scope of the "request" scope, because "enterScope" would fail upon every forward between "request" and nested "request" unless "bar" scope was entered prior to forward. --------------------------------------------------------------------------- by stof at 2012-11-28T16:51:50Z @fabpot why would it be wrong ? If the nested scope was not active when entering a subrequest, there is simply nothing to save --------------------------------------------------------------------------- by stloyd at 2013-01-04T18:16:54Z Any news about this one ? =) --------------------------------------------------------------------------- by stof at 2013-01-04T18:22:58Z @fabpot could you explain which info we are loosing ?
This commit is contained in:
commit
0c63bbdb01
@ -334,8 +334,10 @@ class Container implements IntrospectableContainerInterface
|
||||
unset($this->scopedServices[$name]);
|
||||
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
$services[$child] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
if (isset($this->scopedServices[$child])) {
|
||||
$services[$child] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
}
|
||||
|
||||
// update global map
|
||||
|
@ -261,6 +261,38 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($container->has('a'));
|
||||
}
|
||||
|
||||
public function testEnterScopeRecursivelyWithInactiveChildScopes()
|
||||
{
|
||||
$container = new Container();
|
||||
$container->addScope(new Scope('foo'));
|
||||
$container->addScope(new Scope('bar', 'foo'));
|
||||
|
||||
$this->assertFalse($container->isScopeActive('foo'));
|
||||
|
||||
$container->enterScope('foo');
|
||||
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertFalse($container->isScopeActive('bar'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
|
||||
$a = new \stdClass();
|
||||
$container->set('a', $a, 'foo');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertTrue(isset($services['foo']['a']));
|
||||
$this->assertSame($a, $services['foo']['a']);
|
||||
|
||||
$this->assertTrue($container->has('a'));
|
||||
$container->enterScope('foo');
|
||||
|
||||
$services = $this->getField($container, 'scopedServices');
|
||||
$this->assertFalse(isset($services['a']));
|
||||
|
||||
$this->assertTrue($container->isScopeActive('foo'));
|
||||
$this->assertFalse($container->isScopeActive('bar'));
|
||||
$this->assertFalse($container->has('a'));
|
||||
}
|
||||
|
||||
public function testLeaveScopeNotActive()
|
||||
{
|
||||
$container = new Container();
|
||||
|
Reference in New Issue
Block a user