shutdown
Срабатывает в момент, когда PHP скрипт завершил все свои операции или была вызвана функция exit().
Хук сработает в любых условиях, например, если закончилось время выполнения скрипта или скрипт оборван через exit или как-то еще, поэтому через него удобно ловить какие-то непредвиденную логику и как-то обрабатывать или его удобно использовать когда нужно чтобы, код был выполнен в любой ситуации.
Срабатывает до фактической отправки тела ответа. Можно что-то дописать в body через echo, но заголовки уже менять нельзя.
Принцип работы хука такой: на PHP функцию register_shutdown_function() повешена функция shutdown_action_hook(), которая в свою очередь вызывает хук shutdown:
// Регистрация функции, которая сработает перед завершением работы скрипта
register_shutdown_function( 'shutdown_action_hook' );
// Сама функция
function shutdown_action_hook() {
// Описываемый хук
do_action( 'shutdown' );
wp_cache_close();
}
Использование
add_action( 'shutdown', 'wp_kama_shutdown_action' );
/**
* Function for `shutdown` action-hook.
*
* @return void
*/
function wp_kama_shutdown_action(){
// action...
}
Примеры
#1 Добавление безграничного количества записей
Когда нужно добавить много записей в базу данных, можно столкнуться с проблемой: сервер останавливает работающий скрипт из-за ограничения времени выполнения скрипта (как правило 30 секунд). Это ограничение можно обойти с помощью хука shutdown. Однако, такой обход можно сделать не на всех серверах, т.е. это зависит от настроек сервера (вызывает ли сервер функцию register_shutdown_function() каждый раз при превышении лимита времени работы PHP).
Данный код лишь для примера:
## Запускает процесс генерации записей через добавление к URL параметра init_new_posts_creation.
if ( isset( $_GET['init_new_posts_creation'] ) ) {
// Запускает добавление записей в базу.
add_action( 'init', 'create_new_posts' );
// Когда скрипт будет остановлен сервером, сработает этот хук и запустит указанную функцию.
add_action( 'shutdown', 'reinit_create_new_posts' );
}
## Запускает процесс генерации записей.
## Записывает продолжительность процесса генерации записей в секундах.
function reinit_create_new_posts() {
// пересчитаем то что там у нас набралось...
wp_defer_term_counting(false);
wp_defer_comment_counting(false);
// Запускает процесс генерации записей.
create_new_posts();
}
## Добавляет тестовые записи в базу данных.
function create_new_posts() {
static $index, $bigest_id;
$creat_posts = (int) ( $_GET['init_new_posts_creation'] ?: 10 ); // сколько постов создать?
// функция запустилась первый раз
if( $index === null ){
global $wpdb;
$bigest_id = $wpdb->get_var("SELECT MAX(ID) FROM $wpdb->posts") ?: 1;
$index = $bigest_id;
}
else {
// сколько еще осталось создать?
$creat_posts = $creat_posts - ( $index - $bigest_id );
$bigest_id = $index;
}
// все создано!
if( $creat_posts <= 0 ){
// Записывает время выполнения генерации записей.
update_option( 'time_spent_to_create_posts', timer_stop(), false );
return;
}
// Отключаем операции, которые замедляют добавление записей.
wp_suspend_cache_addition( true );
wp_defer_term_counting( true );
wp_defer_comment_counting( true );
// Генерирует массив, определяющий количество генерируемых записей
$range = range( $bigest_id, $bigest_id + $creat_posts );
foreach ( $range as $id ) {
sleep(1);
// Данные записи.
$post_data = [
'post_title' => 'Заголовок записи ' . $id,
'post_content' => 'Здесь должен быть контент (текст) записи ' . $id,
'post_status' => 'draft', // с таким статусом запись добавляется быстрее,
// потом одним разом сменим у всех добавленных
// записей на publish
];
// Добавляет запись в базу данных.
wp_insert_post( wp_slash( $post_data ) );
$index++;
}
wp_defer_term_counting( false );
wp_defer_comment_counting( false );
}
Список изменений
| С версии 1.2.0 | Введена. |
Где вызывается хук
do_action( 'shutdown' );
Где используется хук в 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_ob_end_flush_all', 1 );
add_action( 'shutdown', '_wp_delete_all_temp_backups' );