Restore output buffer in case of exceptions

php.internals

Mehmet Yavuz Selim Soyturk

18 years ago
Hello, I'm sorry if that's the wrong list. I am neither a PHP nor a webscripting guy so I'm sorry if this does not make sense. I just thought that it could be useful. PHP 5 supports exception handling. When an exception occurs, PHP does stack unwinding so that it restores the state of the script. But an important state of the script does not get restored: the output. Would it not be a good idea if PHP also did some sort of output buffer unwinding? That is the idea: <?php exceptional_ob_start(); echo "Begin\n"; try { echo "Exception\n"; throw new Exception(); } catch (Exception $e) {} echo "End\n"; exceptional_ob_end_flush(); ?> And that would be the only output: Begin End

Antony Dovgal

18 years ago
On 18.11.2007 01:36, Mehmet Yavuz Selim Soyturk wrote:
> That is the idea: > > <?php > > exceptional_ob_start(); > > echo "Begin\n"; > try { > echo "Exception\n"; > throw new Exception(); > } catch (Exception $e) {} > echo "End\n"; > > exceptional_ob_end_flush(); > > ?> > > And that would be the only output: > > Begin > End >
Following this logic, we would also need to "unwind" all file descriptors, database transactions, network connections etc. etc. This makes no sense.
-- Wbr, Antony Dovgal

Alexey Zakhlestin

18 years ago
On 11/18/07, Antony Dovgal <tony@daylessday.org> wrote:
> On 18.11.2007 01:36, Mehmet Yavuz Selim Soyturk wrote: > > That is the idea: > > > > <?php > > > > exceptional_ob_start(); > > > > echo "Begin\n"; > > try { > > echo "Exception\n"; > > throw new Exception(); > > } catch (Exception $e) {} > > echo "End\n"; > > > > exceptional_ob_end_flush(); > > > > ?> > > > > And that would be the only output: > > > > Begin > > End > > > > Following this logic, we would also need to "unwind" all file descriptors, > database transactions, network connections etc. etc. > This makes no sense.
This makes sense, but it's almost impossible to implement it this way :) On the other hand, implementing output-buffer the way it is proposed can actually be possible and it can be really useful edge-cases are not obvious, though
-- Alexey Zakhlestin http://blog.milkfarmsoft.com/

Evert | Rooftop

18 years ago
Mehmet Yavuz Selim Soyturk wrote:
> Hello, > > I'm sorry if that's the wrong list. > > I am neither a PHP nor a webscripting guy so I'm sorry if this does > not make sense. I just thought that it could be useful. > > PHP 5 supports exception handling. When an exception occurs, PHP does > stack unwinding so that it restores the state of the script. But an > important state of the script does not get restored: the output. Would > it not be a good idea if PHP also did some sort of output buffer > unwinding? >
Generally I make sure that the parts of my code that start an output buffer are also responsible for closing the output buffer.. so something like this wouldn't be uncommon in my code.. ob_start(); try { do_something(); } catch (Exception $e) { ob_end_clean(); throw $e; } $data = ob_get_clean();

Edward Z. Yang

18 years ago
Evert | Rooftop wrote:
> Generally I make sure that the parts of my code that start an output > buffer are also responsible for closing the output buffer.. so something > like this wouldn't be uncommon in my code..
Agreed. If you'd like to implement transaction support using PHP's exceptions, you'll need to implement rollback functionality yourself in the catch block.
-- Edward Z. Yang GnuPG: 0x869C48DA HTML Purifier <http://htmlpurifier.org> Anti-XSS Filter [[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA ]]

Mehmet Yavuz Selim Soyturk

18 years ago
On Nov 18, 2007 1:38 AM, Evert | Rooftop <evert@rooftopsolutions.nl> wrote:
> Generally I make sure that the parts of my code that start an output > buffer are also responsible for closing the output buffer.. so something > like this wouldn't be uncommon in my code.. > > > ob_start(); > try { > do_something(); > } catch (Exception $e) { > ob_end_clean(); > throw $e; > } > > $data = ob_get_clean(); >
Thanks for the answers. I wasn't aware of the fact that ob's could nest. So one can manually translate the first try-catch to the second: try { // ... code } catch (Exception $e) { // ... code } ob_start(); try { // ... code ob_end_flush(); } catch (Exception $e) { ob_end_clean(); // ... code } More verbose, but works.
-- Mehmet

Stanislav Malyshev

18 years ago
> That is the idea: > > <?php > > exceptional_ob_start(); > > echo "Begin\n"; > try { > echo "Exception\n"; > throw new Exception(); > } catch (Exception $e) {} > echo "End\n"; > > exceptional_ob_end_flush();
You can do it, I think - just another bufferign inside try() and clean it on exception, then output it after try block ends. Buffers are stackable in PHP.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com