首页 文章

如何让Yii2响应不同的HTTP响应?将在库中创建 .

提问于
浏览
2

我在Yii2上使用FPDF / TCPDF . 两个库(以及其他库)都可以直接将数据发送到客户端 . 所以Yii2的反应是没有必要的 . 它甚至必须关闭 . 我怎样才能做到这一点?

目前我收到以下错误,可以在创建的PDF文件的末尾找到(使用文本编辑器):

yii \ web \ HeadersAlreadySentException:已经在/var/www/html/production-service/vendor/setasign/fpdf/fpdf.php上发送了第1017行的 Headers . 在/ var / www / html / my-app / vendor / yiisoft中/yii2/web/Response.php:378

使用以下代码:

class MyController extends yii\web\Controller {
    public function actionCreatePdf() {
        $pdf = new FPDF();
        ...
        $pdf->Output('D', 'my.pdf');
    }
}

2 回答

  • 1

    使用Response::$isSent属性不可靠 . 只要一切正常,它就可以工作 . 但是如果在响应生成期间遇到异常(例如 FPDF 可能会抛出异常),则会再次获得 HeadersAlreadySentException ,因为错误处理程序会重置响应对象并再次发送它 . 我知道唯一的防弹解决方案是创建不发送任何内容的转储响应对象,并设置为 response 组件:

    class DumbResponse extends \yii\web\Response {
    
        public function send() {
        }
    }
    

    在控制器动作中:

    public function actionCreatePdf() {
        Yii::$app->setComponents([
            'response' => DumbResponse::class
        ]);
    
        $pdf = new FPDF();
        // ...
        $pdf->Output('D', 'my.pdf');
    }
    
  • 1

    要抑制整个Yii2响应,您可以简单地执行此操作:

    public function actionCreatePdf() {
        $pdf = new FPDF();
        ...
        $pdf->Output('D', 'my.pdf');
        Yii::$app->response->isSent = true; // <-------------
    }
    

    isSent设置为true将阻止Yii2向客户端发送给定操作的任何内容( Headers ,cookie) . 请注意,这也将抑制response events - 而不是其他(application eventscontroller events) .

    如果属性设置较晚(在操作结束时),则可以定期向客户端发送前面的异常(内容, Headers ,cookie不会被抑制) .

相关问题