Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP-FPM fastcgi_finish_request reliable?

Tags:

php

fastcgi

After implementing some post-processing in my php script after a fastcgi_finish_request(); statement, I worry about some discrepancies.

Looks like PHP is not executing all the script after fastcgi_finish_request.

In the log files, I can not find a notice regarding this part, no warning, no error or irregularities.

Are there limitations or tips for using fastcgi_finish_request that are not mentioned in the documentation?

like image 566
ledy Avatar asked Jan 07 '13 07:01

ledy


2 Answers

Any explicit or implicit output flushing after calling fastcgi_finish_request() will result in exiting the PHP script without any warnings or errors. In other words, calling flush() after fastcgi_finish_request() has been called will behave like you had called exit() instead of flush().

Here's a PHP ticket that documents the behavior. They've labeled it as "not a bug".

Here's some code that reproduces the issue:

function writestamp($case, $file){
  file_put_contents($file, "". $case . ": " . time() . "" . PHP_EOL, FILE_APPEND);
}

// Flush buffers and stop output buffering
while (@ob_end_flush());

// Destroy session, otherwise request can't be finished
if(session_status() > 1) session_destroy();

$file = tempnam(sys_get_temp_dir(), 'flushbug_');
echo 'Writing 4 timestamps to: '.$file;

// this one gets called
writestamp('1', $file);

// and this
register_shutdown_function('writestamp', '4', $file);

// finish the request
fastcgi_finish_request();

// as does this
writestamp('2', $file);

// but this one does NOT - calling flush() after fastcgi_finish_request() exits PHP without errors or warnings
flush();
writestamp('3', $file);

A simple fix is to call ignore_user_abort(true) right before or after the fastcgi_finish_request call:

ignore_user_abort(true);
fastcgi_finish_request();
like image 132
Riku Räisänen Avatar answered Nov 11 '22 20:11

Riku Räisänen


So far, for us, almost everything works after calling fastcgi_finish_request(). Except, error_log(). It does not log anything after calling this function.

like image 2
vince Avatar answered Nov 11 '22 20:11

vince