Bladeren bron

[FrameworkBundle] fixed output buffering when an error occurs in a sub-request

Fabien Potencier 13 jaren geleden
bovenliggende
commit
c31c512466

+ 6 - 0
src/Symfony/Bundle/FrameworkBundle/HttpKernel.php

@@ -135,6 +135,7 @@ class HttpKernel extends BaseHttpKernel
             $subRequest = $request->duplicate($options['query'], null, $options['attributes']);
         }
 
+        $level = ob_get_level();
         try {
             $response = $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
 
@@ -156,6 +157,11 @@ class HttpKernel extends BaseHttpKernel
             if (!$options['ignore_errors']) {
                 throw $e;
             }
+
+            // let's clean up the output buffers that were created by the sub-request
+            while (ob_get_level() > $level) {
+                ob_get_clean();
+            }
         }
     }
 

+ 49 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/HttpKernelTest.php

@@ -166,4 +166,53 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
             array(HttpKernelInterface::SUB_REQUEST),
         );
     }
+
+    public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
+    {
+        $request = new Request();
+
+        $container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
+        $container
+            ->expects($this->at(0))
+            ->method('getParameter')
+            ->with($this->equalTo('kernel.debug'))
+            ->will($this->returnValue(false))
+        ;
+        $container
+            ->expects($this->at(1))
+            ->method('has')
+            ->with($this->equalTo('esi'))
+            ->will($this->returnValue(false))
+        ;
+        $container
+            ->expects($this->at(2))
+            ->method('get')
+            ->with($this->equalTo('request'))
+            ->will($this->returnValue($request))
+        ;
+
+        $dispatcher = new EventDispatcher();
+        $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
+        $resolver->expects($this->once())
+            ->method('getController')
+            ->will($this->returnValue(function () {
+                ob_start();
+                echo 'bar';
+                throw new \RuntimeException();
+            }));
+        $resolver->expects($this->once())
+            ->method('getArguments')
+            ->will($this->returnValue(array()));
+
+        $kernel = new HttpKernel($dispatcher, $container, $resolver);
+
+        // simulate a main request with output buffering
+        ob_start();
+        echo 'Foo';
+
+        // simulate a sub-request with output buffering and an exception
+        $kernel->render('/');
+
+        $this->assertEquals('Foo', ob_get_clean());
+    }
 }