Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detecting user abort with output buffering enabled in PHP

The Notes section in the function documentation of ignore_user_abort() suggest that PHP cannot detect that a user has aborted the request if no data is sent to the client. This is true for the function connection_status(), too. Unfortunately, I need to detect a user abort (an ajax request that can be cancelled) on a page which makes use of output buffering (and I cannot change that easily.)

Is there any other way of detecting a user abort except using the function connection_status()? Or any specific way to make that function return the correct value? PHP should actually know that the request was aborted, since a FIN packet is received from the client.

I have already tried analyzing the stream metadata of php://input, php://output, php://stdin and php://stdout after reading/writing data in a blocking and non-blocking manner before and after the connection was aborted, but that didn't provide any useful state changes.

like image 211
soulmerge Avatar asked Jun 07 '26 12:06

soulmerge


1 Answers

Silly suggestion, but ... have you tried sending some data to the client, followed by a flush() before you start the output buffering? The only other solution I can think of is to escape the buffer(s), but I can imagine how it could be quite troublesome, as you said.

Maybe a helper to assist with breaking the buffer ...

function OBWanCallback($buffer)
{
    if( OBWan::$isFinished )
    {
        // -- Actual callbacks go here ...
    }

   return $buffer;
}

OBWan::startbuffer('OBWanCallback');
[ // -- Example functionality
    self::$callback = $callback;
    ob_start(self::$callback);
]

// -- in some code far, far away ...

OBWan::suspendbuffer();
[ // -- Example functionality
    self::$buffercache = ob_get_clean();
]

echo " ";
flush();

OBWan::resumebuffer();
[ // -- Example functionality
    ob_start(self::$callback);
    echo self::$buffercache;
    self::$buffercache = "";
]

// -- in some code far, far away ...

OBWan::outputbuffer();
[
    self::$isFinished = true;
    return ob_get_clean();
]

with something to account for the depth of buffers you've implemented, if you have implemented depth.

like image 156
Jeff Parker Avatar answered Jun 09 '26 01:06

Jeff Parker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!