简体   繁体   中英

PHP output buffer control

I have an array of items. There are two "types" or items: a heading row, and a regular row. I want to print the heading only if there are any "regular" rows under it (before the next heading).

(This is a simplification - in practice I wont be able to look at the next item from in the current iteration).

To solve this, I used buffer control. I clear and start the buffer at each heading row, and in each regular row I flush the buffer. So the heading wont print if there is a heading after it (buffer will be cleaned) and will be flushed to user if there is a regular row to "flush" it out.

(psudeo code)

for i in array:
     if i is heading:
          ob_end_clean();
          ob_start();
          echo "header $i";
     else:
          ob_end_flush();
          echo "regular $i"

This works great.

Problem is, I have an option to download the page as a PDF and this broke it. The way it works is if the pdf flag is on, at the top of the page, buffer was started and at the bottom of the code, the buffer was dumped into a variable and sent to the pdf api as a string. Now, the buffer is sent to the user at ob_end_flush() which produces this error when I try to download the pdf:

cannot modify header information - headers already sent.

I like my solution but is there a way to make it work? Or is it a bad solution to begin with? thanks

Instead of outputing to buffer, output to a file buffer instead . At then end just send the whole file (it is a bit tricky but it should work fine if you manage the redirections correctly):

pseudo-code:

for i in array:
     if i is heading:
          // output to file buffer
          echo "header $i";
     else:
          // stop output to file buffer
          echo "regular $i"

My suggestion is, even though you can't look at the next item, I think you could keep track of the previous item. I think this should work regardless of your output method.

$previous = '';
foreach ($rows as $row) {
    if ($row == 'header') {
        // Wait to print header rows depending on what the next row is.
        $previous = $row;
    } else {
        // For regular rows, print the preceding header row (if there is one.)
        echo $previous;
        echo $row; // Print the regular row.
        $previous = ''; // Then clear the saved header row.
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM