欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。

分享  yii\web\HeadersAlreadySentException解决方法

PHP框架 本站 433 0评论

在Yii中使用了第三方模板引擎或访问第三方api的url时,输出模板的时候触发了Yii Response类的异常。bug如下:

An Error occurred while handling another error:

yii\web\HeadersAlreadySentException: Headers already sent in \vendor\topthink\think-template\src\Template.php on line 194. in \vendor\yiisoft\yii2\web\Response.php:366

Stack trace:

#0 \vendor\yiisoft\yii2\web\Response.php(339): yii\web\Response->sendHeaders()

#1 \vendor\yiisoft\yii2\web\ErrorHandler.php(135): yii\web\Response->send()

#2 \vendor\yiisoft\yii2\base\ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\HeadersAlreadySentException))

#3 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\HeadersAlreadySentException))

#4 {main}

Previous exception:

yii\web\HeadersAlreadySentException: Headers already sent in \vendor\topthink\think-template\src\Template.php on line 194. in \vendor\yiisoft\yii2\web\Response.php:366

Stack trace:

#0 \vendor\yiisoft\yii2\web\Response.php(339): yii\web\Response->sendHeaders()

#1 \vendor\yiisoft\yii2\base\Application.php(392): yii\web\Response->send()

#2 \backend\web\index.php(17): yii\base\Application->run()

#3 {main}


随之百度一下,说是在操作echo/var_dump/print_r之后在结尾die或者exit可以解决...唔,测试了一下确实可以,但是!这么丑的解决办法肯定不是最好的方案。如果直接die或者exit的话以后可能会导致各种猎奇问题产生(如:debug记录缺失、cli异常结束、回调方法失效等),那就看一下源码吧。

/**

 * Sends the response headers to the client.

 */

protected function sendHeaders()

{

    if (headers_sent($file, $line)) {

        throw new HeadersAlreadySentException($file, $line);

    }

    if ($this->_headers) {

        foreach ($this->getHeaders() as $name => $values) {

            $name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $name)));

            // set replace for first occurrence of header but false afterwards to allow multiple

            $replace = true;

            foreach ($values as $value) {

                header("$name: $value", $replace);

                $replace = false;

            }

        }

    }

    $statusCode = $this->getStatusCode();

    header("HTTP/{$this->version} {$statusCode} {$this->statusText}");

    $this->sendCookies();

}


在yiiwebResponse里sendHeaders方法执行前进行了headers_sent()的验证,所以导致了异常的产生。解决方法就是在模板输出前先把headers设置好,所以在基类控制器重写了模板输出的fetch()方法,并在执行前先使用Response->send()设置headers。代码如下:

/**

 * 重写模板渲染

 * @access public

 * @param string    $template 模板文件

 * @param array     $vars 模板变量

 * @param array     $config 模板参数

 * @return void

 */

protected function fetch($template, $vars = [], $config = []) : void

{

    Yii::$app->response->send();

    $this->view->fetch($template,$vars,$config);

}


访问API的curl时如下:

public function actionGetip($ip)

    {

        if($ip !=''){

            Yii::$app->response->send();

            $url = 'http://xxx.com/json/'.$ip.'?lang=zh-CN';

            SiteController::curl_get_contents($url);

        }

        else{

            $ips['ip'] =  yii::$app->getRequest()->getUserIP();

            return $ips;

        }

}


参考网址:

https://www.yiichina.com/question/3833 


原文地址:网络

转载请注明: ITTXX.CN--分享互联网 » yii\web\HeadersAlreadySentException解决方法

最后更新:2020-06-11 16:18:57

赞 (3) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽