diff --git a/framework/yii/base/Application.php b/framework/yii/base/Application.php index 42875ae..8a96e94 100644 --- a/framework/yii/base/Application.php +++ b/framework/yii/base/Application.php @@ -137,7 +137,6 @@ class Application extends Module // Allocating twice more than required to display memory exhausted error // in case of trying to allocate last 1 byte while all memory is taken. $this->_memoryReserve = str_repeat('x', 1024 * 256); - register_shutdown_function(array($this, 'end'), 0, false); register_shutdown_function(array($this, 'handleFatalError')); } } @@ -172,6 +171,7 @@ class Application extends Module $this->beforeRun(); $response = $this->getResponse(); $response->begin(); + register_shutdown_function(array($this, 'end'), 0, false); $status = $this->processRequest(); $response->end(); $this->afterRun(); diff --git a/framework/yii/base/HttpException.php b/framework/yii/base/HttpException.php index cce0bb0..88e651f 100644 --- a/framework/yii/base/HttpException.php +++ b/framework/yii/base/HttpException.php @@ -7,6 +7,7 @@ namespace yii\base; +use yii\web\Response; /** * HttpException represents an exception caused by an improper request of the end-user. @@ -43,8 +44,8 @@ class HttpException extends UserException */ public function getName() { - if (isset(\yii\web\Response::$statusTexts[$this->statusCode])) { - return \yii\web\Response::$statusTexts[$this->statusCode]; + if (isset(Response::$httpStatuses[$this->statusCode])) { + return Response::$httpStatuses[$this->statusCode]; } else { return 'Error'; } diff --git a/framework/yii/base/Response.php b/framework/yii/base/Response.php index b89b537..29bddb0 100644 --- a/framework/yii/base/Response.php +++ b/framework/yii/base/Response.php @@ -13,23 +13,29 @@ namespace yii\base; */ class Response extends Component { + /** + * @event Event an event raised when the application begins to generate the response. + */ const EVENT_BEGIN_RESPONSE = 'beginResponse'; + /** + * @event Event an event raised when the generation of the response finishes. + */ const EVENT_END_RESPONSE = 'endResponse'; /** * Starts output buffering */ - public function beginOutput() + public function beginBuffer() { ob_start(); ob_implicit_flush(false); } /** - * Returns contents of the output buffer and discards it + * Returns contents of the output buffer and stops the buffer. * @return string output buffer contents */ - public function endOutput() + public function endBuffer() { return ob_get_clean(); } @@ -38,16 +44,16 @@ class Response extends Component * Returns contents of the output buffer * @return string output buffer contents */ - public function getOutput() + public function getBuffer() { return ob_get_contents(); } /** * Discards the output buffer - * @param boolean $all if true recursively discards all output buffers used + * @param boolean $all if true, it will discards all output buffers. */ - public function cleanOutput($all = true) + public function cleanBuffer($all = true) { if ($all) { for ($level = ob_get_level(); $level > 0; --$level) { @@ -60,11 +66,25 @@ class Response extends Component } } + /** + * Begins generating the response. + * This method is called at the beginning of [[Application::run()]]. + * The default implementation will trigger the [[EVENT_BEGIN_RESPONSE]] event. + * If you overwrite this method, make sure you call the parent implementation so that + * the event can be triggered. + */ public function begin() { $this->trigger(self::EVENT_BEGIN_RESPONSE); } + /** + * Ends generating the response. + * This method is called at the end of [[Application::run()]]. + * The default implementation will trigger the [[EVENT_END_RESPONSE]] event. + * If you overwrite this method, make sure you call the parent implementation so that + * the event can be triggered. + */ public function end() { $this->trigger(self::EVENT_END_RESPONSE); diff --git a/framework/yii/web/Response.php b/framework/yii/web/Response.php index 9d57560..40914c3 100644 --- a/framework/yii/web/Response.php +++ b/framework/yii/web/Response.php @@ -46,11 +46,10 @@ class Response extends \yii\base\Response * @var string the version of the HTTP protocol to use */ public $version = '1.0'; - /** * @var array list of HTTP status codes and the corresponding texts */ - public static $statusTexts = array( + public static $httpStatuses = array( 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', @@ -135,12 +134,12 @@ class Response extends \yii\base\Response public function begin() { parent::begin(); - $this->beginOutput(); + $this->beginBuffer(); } public function end() { - $this->content .= $this->endOutput(); + $this->content .= $this->endBuffer(); $this->send(); parent::end(); } @@ -157,7 +156,7 @@ class Response extends \yii\base\Response throw new InvalidParamException("The HTTP status code is invalid: $value"); } if ($text === null) { - $this->statusText = isset(self::$statusTexts[$this->_statusCode]) ? self::$statusTexts[$this->_statusCode] : ''; + $this->statusText = isset(self::$httpStatuses[$this->_statusCode]) ? self::$httpStatuses[$this->_statusCode] : ''; } else { $this->statusText = $text; } @@ -178,15 +177,17 @@ class Response extends \yii\base\Response public function renderJson($data) { - $this->getHeaders()->set('content-type', 'application/json'); + $this->getHeaders()->set('Content-Type', 'application/json'); $this->content = Json::encode($data); + $this->send(); } public function renderJsonp($data, $callbackName) { - $this->getHeaders()->set('content-type', 'text/javascript'); + $this->getHeaders()->set('Content-Type', 'text/javascript'); $data = Json::encode($data); $this->content = "$callbackName($data);"; + $this->send(); } /** @@ -197,6 +198,17 @@ class Response extends \yii\base\Response { $this->sendHeaders(); $this->sendContent(); + + if (function_exists('fastcgi_finish_request')) { + fastcgi_finish_request(); + } else { + for ($level = ob_get_level(); $level > 0; --$level) { + if (!@ob_end_flush()) { + ob_clean(); + } + } + flush(); + } } public function reset()