shutdown
Fires when the PHP script has completed all its operations or exit() has been called.
The hook fires under any conditions, for example when the script execution time expires or the script is stopped with exit or another mechanism. It is therefore useful for catching and handling unexpected logic or whenever code must run in every situation.
The response body may not yet have been sent when the hook fires. Whether headers can still be changed depends on whether they have already been sent.
The hook works as follows: the shutdown_action_hook() function is registered with PHP's register_shutdown_function(), and that function fires the shutdown hook:
// Register a function that runs before the script terminates.
register_shutdown_function( 'shutdown_action_hook' );
// The function itself.
function shutdown_action_hook() {
// The hook described here.
do_action( 'shutdown' );
wp_cache_close();
}
Usage
add_action( 'shutdown', 'wp_kama_shutdown_action' );
/**
* Function for `shutdown` action-hook.
*
* @return void
*/
function wp_kama_shutdown_action(){
// action...
}
Examples
#1 Add an unlimited number of posts
When adding many posts to the database, the server may stop the script because of its execution time limit, normally 30 seconds. The shutdown hook can work around this limit on servers that call register_shutdown_function() whenever the PHP execution time limit is exceeded.
This code is only a demonstration:
## Start post generation through the init_new_posts_creation URL parameter.
if ( isset( $_GET['init_new_posts_creation'] ) ) {
// Start adding posts to the database.
add_action( 'init', 'create_new_posts' );
// When the server stops the script, this hook runs the specified function.
add_action( 'shutdown', 'reinit_create_new_posts' );
}
## Restart the post generation process.
## Record the duration of post generation in seconds.
function reinit_create_new_posts() {
// Recalculate accumulated counts.
wp_defer_term_counting(false);
wp_defer_comment_counting(false);
// Restart post generation.
create_new_posts();
}
## Add test posts to the database.
function create_new_posts() {
static $index, $bigest_id;
$creat_posts = (int) ( $_GET['init_new_posts_creation'] ?: 10 ); // Number of posts to create.
// The function is running for the first time.
if( $index === null ){
global $wpdb;
$bigest_id = $wpdb->get_var("SELECT MAX(ID) FROM $wpdb->posts") ?: 1;
$index = $bigest_id;
}
else {
// Determine how many posts remain.
$creat_posts = $creat_posts - ( $index - $bigest_id );
$bigest_id = $index;
}
// Everything has been created.
if( $creat_posts <= 0 ){
// Record the post generation execution time.
update_option( 'time_spent_to_create_posts', timer_stop(), false );
return;
}
// Disable operations that slow down post insertion.
wp_suspend_cache_addition( true );
wp_defer_term_counting( true );
wp_defer_comment_counting( true );
// Generate the range that determines the number of posts to create.
$range = range( $bigest_id, $bigest_id + $creat_posts );
foreach ( $range as $id ) {
sleep(1);
// Post data.
$post_data = [
'post_title' => 'Post title ' . $id,
'post_content' => 'The post content should be here ' . $id,
'post_status' => 'draft', // Posts are inserted faster with this status.
// Change all added posts to publish afterward.
];
// Add the post to the database.
wp_insert_post( wp_slash( $post_data ) );
$index++;
}
wp_defer_term_counting( false );
wp_defer_comment_counting( false );
}Changelog
| Since 1.2.0 | Introduced. |
Where the hook is called
do_action( 'shutdown' );
Where the hook is used in WordPress
add_action( 'shutdown', array( $this, 'restore_temp_backup' ), 10, 0 );
add_action( 'shutdown', array( $this, 'delete_temp_backup' ), 100, 0 );
add_action( 'shutdown', '_wp_cron' );
add_action( 'shutdown', 'wp_ob_end_flush_all', 1 );
add_action( 'shutdown', '_wp_delete_all_temp_backups' );