At 01:37 07/01/2003, Joseph Tate wrote:
Well, according to my highly technical methods of deduction (fprintf(stderr,
"Inside sapi_shutdown");)  sapi_shutdown is never called when serving a PHP
request when served using mod4_php under Apache.  This is because the
shutdown_wrapper never gets initialized as a cleanup function.  This because
the php_init_handler is never called, and this happens for some reason
undivinable by me.  Perhaps it should be used, and we should execute regular
shutdown functions there, and proceed to use php_request_shutdown in the way
it was used prior to php 4.1.x i.e. after the connection has closed (on
apache anyway) and while PHP is still in memory.  We'll get the added
benefit of (on Apache systems anyway) a significant performance gain as the
cleanup phase happens without the client having to wait for it.
You must have messed up on your analysis, as php_init_handler() is certainly being called, and so is sapi_shutdown(). Place an abort() in them, it won't take more than a couple of minutes to know that for certain :)
I would guess that the source of the problem is that sapi_shutdown() is simply not the function you're looking for. You're probably looking for sapi_deactivate().

Here is my vision based on my understanding of the inner workings of PHP.

There are at least four types of shutdown functions in PHP (not including
PHP space (identified by the use of register_shutdown_function)
module_shutdown (called when a module is to clean up after itself)
sapi_shutdown (not used under many sapi implementations)
there may also be zend and tsrm shutdown functions.
Not quite.

First off, if we're talking about register_shutdown_function(), then we're dealing with activate/deactivate functions, and not startup/shutdown functions. In the old terms, still used by modules, we're dealing with RINIT/RSHTDOWN (request-init, request-shutdown).
Activate (rinit) / deactivate (rshutdown) functions get called in the beginning and end of each request, respectively. In that regard, there are *plenty* of them. Activate/deactivate functions are called for the engine, SAPI, output buffering, whatnot. The engine, in turn, calls the activate/deactivate callbacks that are available in modules, if available. One of the deactivate actions in php_request_shutdown is to call the userland-registered shutdown functions.

SAPI is just one of the many subsystems which are initialized/destroyed by php_requset_startup() and php_request_shutdown(). There's nothing special about it.

php_shutdown seems to always be a call to shutdown wheras the remainder are
called when shutdown occurs.
Didn't quite understand that..?

Thus the cleanup/shutdown routines should be
called in this order:

load and run PHP script
call sapi_shutdown
which calls module_shutdown on all used modules
and then executes register_shutdown_functions
and then calls php_request_shutdown in a server specific manner (in apache
as a cleanup_function after the http communication has terminated)
which (under platforms that support it) executes
before cleaning up PHP and freeing memory.
There are many problematic things about this layout. Suffice to say that intimately knowing the shutdown order in PHP, I don't think there are any conceptual problems with it. Again, there's nothing inherent in SAPI that makes it the function of choice to be the root of all deactivation calls, as it is just one of the many subsystems in PHP. PHP's main deactivation function is php_request_shutdown(), and it calls sapi_deactivate(), because it's one of the subsystems that requires deactivation. It's the responsibility of the SAPI module to figure out the best way to ensure that php_request_shutdown() gets called at the end of each request.

SAPI was developed for abstracting the server, but it seems that instead it
has been worked around rather than extended for the individual servers.  I
speak in generalizations, but that's what it looks like.  In my book, all
php internal functions should be called through the appropriate SAPI
functions, which are called by a main function for each sapi implementation.
There is too much deviation from this, thereby crippling SAPI.  Either use
it or cut it out completly.

These changes are too large for a minor version release, i.e. 4.3.1, but
perhaps for 4.4/5.0?  I'd be willing to put some time into reworking the
SAPI system.
I think that these harsh thoughts are mostly due to the problems in the initial analysis. SAPI is really working very very well as it is :)


PHP Development Mailing List <>
To unsubscribe, visit:

Reply via email to