Посмотрел на тему про смену пути в деструкторе и обнаружил вот такую фишку:
Изначальный скрипт
PHP код:
<?php
class a {
function __destruct() {
echo "Destruct ".getcwd();
}
}
echo "Main ".getcwd();
$a = new a;
echo "test";
?>
Результат:
Код:
Main Z:\home\test\www
test
Destruct Z:\usr\local\apache\bin
Логично, скрипт выполняется до конца, после чего вызываются деструкторы (в котором меняется путь).
Теперь изменим его
PHP код:
<?php
class a {
function __destruct() {
echo "Destruct ".getcwd();
}
}
echo "Main ".getcwd();
new a;
echo "test";
?>
Результат:
Код:
Main Z:\home\test\www
Destruct Z:\home\test\www
test
В целом, тоже логично. Так как объект никуда не записывается, то он не нужен и вызывается деструктор, после чего скрипт продолжает работу.
Двигаемся дальше
PHP код:
<?php
class a {
function __destruct() {
echo "Destruct ".getcwd()."\n";
}
}
echo "Main ".getcwd()."\n";
$a = unserialize(stripslashes($_GET['c']));
echo "\ntest\n";
?>
Код:
c=O:1:"a":0:{}
Main Z:\home\test\www
test
Destruct Z:\usr\local\apache\bin
c=O:1:"a":0:{X}
Main Z:\home\test\www
Destruct Z:\home\test\www
Notice: unserialize() : Error at offset 12 of 13 bytes
test
Следовательно, не смотря на то, что при десериализации возникла ошибка (из-за неправильного описания параметров), объект все равно создался.
Но десериализация вернула false и объект никуда не записался и его деструктор выполнился прямо в этом месте, а не в конце.
Продолжаем разговор
PHP код:
<?php
class a {
function __destruct() {
echo "Destruct ".getcwd()."\n";
echo "Test object params ".$this->X;
}
}
echo "Main ".getcwd()."\n";
$a = unserialize(stripslashes($_GET['c']));
echo "\ntest\n";
?>
Код:
c=O:1:"a":1:{s:1:"X";s:7:"TEST_OK";Z}
Main Z:\home\test\www
Destruct Z:\home\test\www
Test object params TEST_OK
Notice: unserialize() : Error at offset 34 of 35 bytes
test
Итог:
1) При вызове ошибки в описании параметров объекта в десериализации, он все равно создатся и у него выполнится деструктор
2) Так как при ошибке unserialize вернет false, то объект станет никому не нужным и его деструктор вызовется сразу после десериализации. То есть мы можем контролировать в какой именно точке вызвать деструктор.
3) При ошибке в описании параметров в десериализации все ранее описанные параметры нормально срабатывают.
Пригодится, если в деструкторе работают с чем-нибудь глобальным (переменные, файлы и тп.)