Вернуть файл xml, избегая его повторения - PullRequest
0 голосов
/ 08 января 2020

Я знаю, что не следует использовать echo в контроллерах, но я не понимаю, что я должен использовать, чтобы вернуть xml для его загрузки. Обратите внимание: это не файл на сервере , это просто строка:

public function export()
{
    $this->autoRender = false;

    $id = $this->request->getQuery('id');
    $invoice = $this->Invoices->get($id, ['contain' => ['Customers', 'ItemInvoices' => ['ItemProformas' => ['ItemDeliveryNotes' => ['ItemOrders' => ['Orders' => ['Customers']]]]]]]);

    $fpr = new ExportInvoice();
    $fpr->SetInvoice($invoice);

    header('Content-type: text/xml');
    header('Content-Disposition: attachment; filename="' . $fpr->getFilename() . '"');

    $xml = $fpr->asXML();
    echo $xml;
}

на самом деле работает, как и ожидалось: браузер загружает файл с указанным именем файла и его содержимое $xml значение.

Но в конце файла есть предупреждения о заголовках:

Warning (512): Unable to emit headers. Headers sent in file=/home/mark/myproject/src/Controller/InvoicesController.php line=130 [CORE/src/Http/ResponseEmitter.php, line 51]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/mark/myproject/src/Controller/InvoicesController.php:130) [CORE/src/Http/ResponseEmitter.php, line 152]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/mark/myproject/src/Controller/InvoicesController.php:130) [CORE/src/Http/ResponseEmitter.php, line 181]
Warning (2): Cannot modify header information - headers already sent by (output started at /home/mark/myproject/src/Controller/InvoicesController.php:130) [CORE/src/Http/ResponseEmitter.php, line 181]

Насколько я знаю, это связано с использованием echo в контроллер. Может случиться так, что перед отправкой заголовка есть выход, а затем предупреждения.

Как правильно заменить функцию echo?

Ответы [ 2 ]

4 голосов
/ 08 января 2020

До получения документов, вы можете использовать платформу для этого, ознакомьтесь с тем, как Отправка строки в виде файла

public function export()
{
    $this->autoRender = false;

    $id = $this->request->getQuery('id');
    $invoice = $this->Invoices->get($id, ['contain' => ['Customers', 'ItemInvoices' => ['ItemProformas' => ['ItemDeliveryNotes' => ['ItemOrders' => ['Orders' => ['Customers']]]]]]]);

    $fpr = new ExportInvoice();
    $fpr->SetInvoice($invoice);

    // header('Content-type: text/xml');
    // header('Content-Disposition: attachment; filename="' . $fpr->getFilename() . '"');

    $xml = $fpr->asXML();
    $response = $this->response;
    $response = $response->withStringBody($xml);
    // use $response->body($xml); for versions before 3.4.0
    $response = $response->withType('xml');
    $response = $response->withDownload($fpr->getFilename());
    return $response;
}
0 голосов
/ 08 января 2020

Просто используйте die() или exit()

public function export()
{
    $this->autoRender = false;

    $id = $this->request->getQuery('id');
    $invoice = $this->Invoices->get($id, ['contain' => ['Customers', 'ItemInvoices' => ['ItemProformas' => ['ItemDeliveryNotes' => ['ItemOrders' => ['Orders' => ['Customers']]]]]]]);

    $fpr = new ExportInvoice();
    $fpr->SetInvoice($invoice);

    if (!headers_sent())
    {
        header('Content-type: text/xml');
        header('Content-Disposition: attachment; filename="' . $fpr->getFilename() . '"');
    }
    else
    {
        //Do something else to let them know they can't expect a file
        die();
    }

    die($fpr->asXML());
}

Обновление

Относительно комментария

Использование return , exit или d ie уже подробно объясняется в этом вопросе php -выйди или вернись-что-лучше , что-есть -The-различия-в-д ie и-выход-in php

...