PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, March 16, 2022

[FIXED] Return an xml file avoiding to echo it

 March 16, 2022     cakephp, php, xml     No comments   

Issue

I know one should not use echo in controllers, but I don't understand what I should use to return an xml in order to download it. Please note, it's not a file on the server, it's just a string:

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;
}

it actually works as expected: the browser download a file with the given filename and its content is the $xml value.

But at the end of the file there are warnings about headers:

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]

As far as I know this is due to the usage of echo in controller. It may happens there's an output before sending the header, and then the warnings.

What's the correct way to replace the echo function?


Solution

Just use die() or 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());
}

Update

Regarding the comment

Using return, exit or die is already explained in detail in this question php-exit-or-return-which-is-better, what-are-the-differences-in-die-and-exit-in-php



Answered By - Maximilian Fixl
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing