Register shutdown function: примеры (PHP)

Использование register_shutdown_function для обработки завершения скрипта
Раздел: Управление выполнением
register_shutdown_function(callable $callback, mixed ...$args): void

Функция register_shutdown_function в PHP

Назначение и применение

Функция register_shutdown_function регистрирует callback-функцию, которая выполняется после завершения основного скрипта или при возникновении фатальной ошибки. Эта возможность применяется для задач финализации: логирования, отправки статистики, закрытия соединений с базами данных, очистки временных файлов.

Аргументы функции

Функция принимает переменное количество аргументов:

register_shutdown_function(callable $callback, mixed ...$args): void
  • $callback — вызываемая функция, может быть строкой с именем функции, массивом [класс, метод] или анонимной функцией.
  • ...$args — необязательные аргументы, передаваемые в callback-функцию при вызове.

Примеры использования register_shutdown_function

Базовый пример с анонимной функцией
register_shutdown_function(function() {
    echo 'Скрипт завершён';
});
echo 'Основной поток выполнения. ';
Основной поток выполнения. Скрипт завершён
Передача аргументов в обработчик
register_shutdown_function(function($msg, $code) {
    echo "$msg. Код: $code";
}, 'Завершение работы', 200);
Завершение работы. Код: 200
Использование метода класса
class Logger {
    public static function log() {
        echo 'Логирование завершения';
    }
}
register_shutdown_function(['Logger', 'log']);
Логирование завершения

Альтернативные функции в PHP

set_exception_handler

Устанавливает обработчик непойманных исключений. Используется для централизованной обработки исключений вместо регистрации завершающей функции для каждой операции.

set_error_handler

Определяет пользовательский обработчик ошибок. Обрабатывает предупреждения и ошибки, но не фатальные. Часто используется вместе с register_shutdown_function для обработки всех типов ошибок.

__destruct

Магический метод, вызываемый при уничтожении объекта. Подходит для освобождения ресурсов конкретного объекта, в то время как register_shutdown_function работает на уровне всего скрипта.

Аналоги в других языках программирования

Python: atexit
import atexit
def cleanup():
    print('Очистка ресурсов')
atexit.register(cleanup)
print('Основной код')
Основной код
Очистка ресурсов
JavaScript: window.onbeforeunload
window.addEventListener('beforeunload', function(event) {
    console.log('Страница будет закрыта');
});

В JavaScript нет прямого аналога, но событие beforeunload позволяет выполнить код перед закрытием страницы.

Java: Runtime.addShutdownHook
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    System.out.println('Завершение JVM');
}));

Типичные ошибки при использовании

Попытка вывода после отправки заголовков
header('Content-Type: text/html');
register_shutdown_function(function() {
    header('Location: /new-page'); // Ошибка!
});
Warning: Cannot modify header information - headers already sent
Использование несуществующих функций
register_shutdown_function('undefined_function');
Fatal error: Uncaught Error: Call to undefined function undefined_function()
Бесконечные циклы в обработчике
register_shutdown_function(function() {
    while(true) { // Бесконечный цикл
        file_put_contents('log.txt', time());
    }
});

Скрипт может не завершиться, потреблять ресурсы сервера.

Изменения в последних версиях PHP

PHP 8.0: Статический анализ аргументов

Улучшена проверка типов аргументов при вызове. Передача некорректного callable вызывает TypeError.

PHP 7.1: Возвращаемые значения

Ранее возвращаемые значения shutdown-функций игнорировались. Сейчас они доступны через debug_backtrace, но не влияют на выполнение.

PHP 5.4: Улучшенная обработка анонимных функций

Были внесены улучшения для корректной работы замыканий в shutdown-функциях.

Расширенные примеры использования

Отслеживание времени выполнения скрипта
Пример php
$start = microtime(true);
register_shutdown_function(function() use ($start) {
    $time = microtime(true) - $start;
    file_put_contents('time.log', "Время выполнения: $time сек");
});
// Длительная операция
for($i = 0; $i < 1000000; $i++) {}
Обработка фатальных ошибок
Пример php
register_shutdown_function(function() {
    $error = error_get_last();
    if($error && $error['type'] === E_ERROR) {
        mail('admin@site.com', 'Фатальная ошибка', print_r($error, true));
    }
});
// Вызов несуществующей функции
nonexistent_function();
Цепочка завершающих функций
Пример php
register_shutdown_function(function() {
    echo 'Первая функция. ';
});
register_shutdown_function(function() {
    echo 'Вторая функция. ';
});
register_shutdown_function(function() {
    echo 'Третья функция.';
});
Первая функция. Вторая функция. Третья функция.
Использование с сессиями
Пример php
session_start();
register_shutdown_function(function() {
    session_write_close();
    echo 'Сессия сохранена';
});
$_SESSION['last_visit'] = time();

PHP register_shutdown_function function comments

En
Register shutdown function Register a function for execution on shutdown