Как убрать за собой в PHP

Источник: «How to Clean After Oneself in PHP»
Как убрать за собой в PHP : используйте register_shutdown_function, __destruct и try-catch-finally, чтобы убедиться, что уборка выполняется всегда

Оглавление

Хотя создание эффективного и функционального кода имеет огромное значение, не менее важно обеспечить правильное завершение использования ресурсов. Существует множество ситуаций, когда очень важно освободить блокировку, закрыть соединение или завершить работу с файлом. В этой статье мы рассмотрим три важные функции, помогающие коду всегда убирать за собой, даже в случае ошибки: register_shutdown_function(), деструктор объектов __destruct() и команда try-catch-finally.

register_shutdown_function()

В ранних версиях PHP появилась функция register_shutdown_function(). Она позволяет зарегистрировать функцию, которая будет выполнена, при завершении выполнения сценария, независимо от того, завершился ли он успешно или столкнулся с ошибкой. Эта функция особенно полезна, когда задачу очистки сложно связать с задачей инициализации. Регистрируя её для завершения сценария, вы гарантируете, что всё остальное произойдёт раньше.

<?php
function cleanupFunction() {
// Выполните здесь задачи по очистке
// Закройте открытые файлы, освободите ресурсы и т. д.
}

register_shutdown_function('cleanupFunction');

// Остальной PHP-код
?>

Зарегистрированная функция выполняется после завершения скрипта. В этот момент PHP уже закрыл поток вывода, поэтому вывести что-либо в браузер невозможно. В частности, echo и print уже не работают.

Деструктор объекта __destruct()

В объектно-ориентированном программировании метод __destruct() определяет, что происходит, когда на объект больше нет ссылок, или когда он явно уничтожается. Это мощный механизм для освобождения ресурсов, связанных с объектом: деструктор автоматически вызывается при уничтожении объекта.

Это может произойти при завершении работы скрипта, как мы видели на примере предыдущей функции register_shutdown_function(). Однако это также происходит непосредственно, когда на объект больше нет ссылок. Это означает, что локальный объект в методе немедленно уничтожается при завершении метода.

<?php

class Session {
public function __construct() {
// Подключение ресурсов при инициализации объекта
print "Started\n";
}

public function __destruct() {
// Освобождение ресурсов при уничтожении объекта
print "Finished\n";
}
}

function foo() {
$session = new Session();

// Ничего не нужно делать, __destruct вызывается автоматически
}

foo();
// Started
// Finished

?>

Реализовав метод __destruct() в классе, код может инкапсулировать логику освобождения ресурсов в самом объекте.

Обработка исключений

Обработка исключений — это фундаментальный аспект написания надёжного и стабильного PHP-кода. Здесь мы отклонимся от его первоначальной цели, чтобы воспользоваться преимуществами критически важной функции: finally.

finally выполняется всегда, независимо от того, возникло исключение или нет. Следовательно, после запуска блока try всегда используется блок finally. Между ними могут происходить исключения, которые могут быть пойманы или нет: что бы ни случилось, finally будет вызван.

А поскольку catch — необязательный пункт, можно написать корректный код вроде этого:

<?php
try {
// Записать файл на диск
file_put_contents($path, 1);

} finally {
// Освободить временный файл и т. д.
unlink($path);
}

?>

Этот синтаксис не блокирует исключения, которые будут переданы как есть, если они есть. Тем не менее блок finally будет выполняться всегда, что делает его обязательным шагом, на котором может быть очищено всё что угодно.

Правило бойскаута

Оставлять ресурсы как минимум такими же чистыми, какими они были до начала выполнения, также известно как правила бойскаута. PHP предлагает три способа убедиться в том, что очистка происходит независимо от количества возникающих ошибок (правда, если речь не идёт о Segmentation fault).

Функция register_shutdown_function() предоставляет возможность очистки в последний момент, после того как всё приложение было запущено; метод __destruct() даёт возможность очистки при выходе метода и, finally, предлагает то же самое внутри последовательности кода.

Наконец, существуют функции PHP, которые сами занимаются такой очисткой. Например, tmpfile() предоставляет временный файл, который будет удалён в конце сценария; соединения с базами данных откатывают все открытые и незавершённые транзакции.

Уборка за своим кодом очень важна.

Дополнительные материалы

Предыдущая Статья

Руководство для начинающих по блочной модели CSS

Следующая Статья

Androxgh0st нацелен на Laravel приложения?