Как позволить Yii2 отвечать другим HTTP-ответом? Будет создан в библиотеке. - PullRequest
0 голосов
/ 25 апреля 2018

Я использую FPDF / TCPDF с Yii2.Обе библиотеки (а также и другие) могут напрямую отправлять данные клиенту.Так что ответ Yii2 не нужен.Это даже должно быть выключено.Как я могу это сделать?

В настоящее время я получаю следующую ошибку, которую можно найти в конце созданного файла PDF (с помощью текстового редактора):

yii \ web \HeadersAlreadySentException: заголовки уже отправлены в /var/www/html/production-service/vendor/setasign/fpdf/fpdf.php по строке 1017. в / 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 ]

0 голосов
/ 25 апреля 2018

Использование 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');
}
0 голосов
/ 25 апреля 2018

Чтобы подавить весь ответ Yii2, вы можете просто сделать это:

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

isSent, установленный в значение true, предотвратит отправку Yii2 чего-либо (заголовки, файлы cookie) клиенту для выполнения данного действия. Обратите внимание, что это также подавит события ответа - но не другие ( события приложения , события контроллера ).

Если свойство устанавливается поздно (в конце действия), предыдущие исключения могут регулярно отправляться клиенту (содержимое, заголовки, файлы cookie не подавляются).

...