Can I rely on register_shutdown_function() being called on SIGTERM, if pcntl_signal() is set up?

PHP user shutdown functions are called during ordinary process termination, somewhat analogous to functions registered with atexit in other programming languages. An explicit exit or implicit exit at end-of-script is an ordinary process termination.

Signal death, however, is abnormal process termination. The default behavior for SIGTERM (and the mandatory behavior for SIGKILL) is to terminate the running process immediately, without running any cleanup handlers.

When you intercept a SIGTERM with pcntl_signal, you are installing different behavior and giving yourself the opportunity to experience ordinary process termination.

Yes, you can rely on this behavior. While the main manual entry is not explicit, the rest of the "Note" you quote reads:

[Y]ou can use pcntl_signal() to install a handler for a SIGTERM which uses exit() to end cleanly.


In addition to pilcrows correct answer:

The signal handler is necessary for changing the behavior of the signal (i.e. instead of the default action). Whatever happens after that is irrelevant.

You might use the signal handler to just do emergency cleanup and then call posix_kill(getmypid(), SIGKILL); to force termination without cleanup. If you exit() here, normally the shutdown sequence (i.e. calling of all destructors, shutdown handlers etc.) is initiated.

When you say in addition to, you're not strictly correct. You need to use the signal handler instead and may additionally have a shutdown handler. [referring to your comment]

Be also aware that calling exit() after the shutdown sequence has been initiated will abort the current part of it (i.e. when you're currently inside a shutdown handler and exit() gets called, all subsequent shutdown handlers are ignored - but e.g. destructors will still be called). Ideally you have some check against this:

register_shutdown_function(function() { $GLOBALS["#__in_shutdown"] = 1; });

and have a check around exit():

if (empty($GLOBALS["#__in_shutdown"])) {
    exit;
}

Just in case you want to be really safe unless someone fires SIGKILL on it.

Note that 7.0 or 7.1 won't change this behavior; all what changes in 7.1 is declare(ticks=1); being superfluous, the exhibited behavior is still the same.