Деструкторы в PHP. Необходимость. Возможность замены. (Destructors)
PHP принадлежит с семейству языков с «автоматической сборкой мусора» или garbage collection. В программировании, сборка мусора (англ. garbage collection, GC) — одна из форм автоматического управления памятью. Специальный код, называемый сборщиком мусора (garbage collector), пытается освободить память, использованную объектами, которые уже не будут востребованы приложением — т.е. производит сборку мусора.
Сборка мусора предотвращает утечки памяти, которые возможны при ручном кодировании выделения и освобождения памяти, а также упрощает сам процесс программирования. Недостатком сборки мусора является меньшая эффективность, как по скорости, так и по объёму используемой памяти. Кроме освобождения памяти, сборщик мусора также дефрагментирует (уплотняет) объекты в памяти системы, перемещая их так, что бы они занимали сплошную область памяти, что благоприятно отражается на производительности системы.
Базовые принципы работы сборщика мусора:
1. определение объектов программы, которые в будущем не будут использоваться;
2. освобождение памяти, занимаемой этими объектами.
Хотя в общем случае невозможно точно определить момент, когда объект был использован в последний раз и больше не нужен, сборщики мусора используют консервативные оценки, позволяющие определить, что в будущем объект уже не будет использоваться. Например, если в системе нет больше ссылок на данных объект — то он больше не может быть использован программой. Этот критерий используется большинством современных сборщиков мусора, в том числе и PHP.
В связи с этим при проектировании и программинге php-приложений деструкторы (какими вы помните их по С++) вам в большинстве случаев не должны понадобиться, и в основном деструкторы в PHP применяют для закрытия соединения с БД, конечной записи в и/или закрытия файлов или других отложенных операций.
В качестве примеров использования деструкторов можно привести следующее.
PHP4
В PHP 4.xx нет механизма деструкторов, поэтому иx приходится эмулировать посредством методов вида free() и flush(), close() и т.п., а также с помощью использования функции
register_shutdown_function.
Пример:
<?php
// Класс, упрощающий ведение разного рода журналов.
class FileLogger {
var $_f; // открытый файл
var $_name; // имя журнала
var $_lines = array(); // накапливаемые строки
// Создает новый файл журнала или открывает дозапись в конец
// существующего. Параметр $name - логическое имя журнала.
function FileLogger($name, $fname) {
$this->_name = $name;
$this->_f = fopen($fname, "a+");
}
// Добавляет в журнал одну строку. Она не попадает в файл сразу
// же, а накапливается в буфере - до самого закрытия (close()).
function log($str) {
// Каждая строка предваряется текущей датой и именем журнала.
$prefix = "[".date("Y-m-d_h:i:s ")."{$this->name}] ";
$str = preg_replace('/^/m', $prefix, rtrim($str));
// Сохраняем строку.
$this->_lines[] = $str."\n";
}
// Закрывает файл журнала. Должна ОБЯЗАТЕЛЬНО вызываться
// в конце работы с объектом!
function close() {
// Вначале выводим все накопленные данные.
fputs($this->_f, join("", $this->_lines));
// Затем закрываем файл.
fclose($this->_f);
}
}
$test = new FileLogger("test_log", "F:\\WWW\\htdocs\\log.log");
$test->log("hello, world!");
// Some actions...
$test->close();
?>
PHP5
В PHP 5.xx, постороенном на новом ядре
Zend 2 реализована поддержка деструкторов.
Деструктор – это специальный метод класса с именем __destruct() (
Constructors and Destructors in PHP5), который будет гарантированно вызван при потере последней ссылки на объект в программе. Так как деструктор запускается самим PHP, он не должен содержать никаких параметров.
Пример:
<?php ## Деструкторы.
// Класс, упрощающий ведение разного рода журналов.
class File_Logger {
public $f; // открытый файл
public $name; // имя журнала
public $lines = array(); // накапливаемые строки
public $t;
// Создает новый файл журнала или открывает дозапись в конец
// существующего. Параметр $name - логическое имя журнала.
public function __construct($name, $fname) {
$this->name = $name;
$this->f = fopen($fname, "a+");
}
// Гарантировано вызывается при уничтожении объекта.
// Закрывает файл журнала.
public function __destruct() {
// Вначале выводим все накопленные данные.
fputs($this->f, join("", $this->lines));
// Затем закрываем файл.
fclose($this->f);
}
// Добавляет в журнал одну строку. Она не попадает в файл сразу
// же, а записывается в буфер и остается там до вызова __destruct().
public function log($str) {
// Каждая строка предваряется текущей датой и именем журнала.
$prefix = "[".date("Y-m-d_h:i:s ")."{$this->name}] ";
$str = preg_replace('/^/m', $prefix, rtrim($str));
// Сохраняем строку.
$this->lines[] = $str."\n";
}
}
$test = new File_Logger("test_log", "F:\\WWW\\htdocs\\log2.log");
$test->log("hello, world!");
// Some actions...
?>
Информационные ресурсы
-
http://php.net
-
PHP 5 (В подлиннике) Котеров Д., Костарев А. BHV-Санкт-Петербург
-
Freedom is not garbage; but managing garbage is freedom
-
Сборка мусора. (2005, декабря 21). Википедия,. Retrieved 16:44, января 25, 2006 from
-
http://www.zend.com
11