vedi se questo esempio puo' tornarti utile:
codice:
class Test {
private $__phrase;
final function __construct($__phrase = 'none', $forceException = false) {
$this->__phrase = $__phrase;
if($forceException)
$this->throwError();
}
final public function throwError() {
throw new Exception('
This is an exception ['.$this.'] .');
}
final function __destruct() {
echo '<hr />'.$this->__phrase;
}
}
// forzare l' eccezione col metodo [ $t prima del try, esiste ]
$t = new Test('destructor will be called ?');
try {
$t->throwError();
}
catch(Exception $e) {
echo $e->getMessage();
}
if($t)
unset($t);
echo '
----------------------------------';
// forzare l' eccezione nel costruttore
// [ $z nel try che non viene eseguito causa eccezione, $z non esiste ]
try {
$z = new Test('destructor will be called in constructor ?', true);
}
catch(Exception $e) {
echo $e->getMessage();
}
Comunque effettivamente c'e' una "stranezza" ... concettualmente e' giusto che nel try, con l' oggetto creato dentro questo, ovvero $z, il distruttore non venga preso affatto in considerazione, visto che $z in teoria non esiste perche' il try non passa causa throw di Exception, pero' e' anche vero che tecnicamente $z esiste, poiche' l' exception scrive anche l' Object id ... e l' object id se presente, significa che esiste un object altrimenti darebbe un notice o un null ...
tutto questo forse e' comunque sensato o forzatamente fatto cosi' poiche' se fallisce la costruzione di un oggetto, visto che esiste un' eccezione, questo non deve essere usato, quindi nemmeno il suo distruttore.
[editato]
probabilmente l' object esiste localmente dentro la chiamata alla classe , quindi viene eliminato dalla garbage collection appena viene richiamato il catch fuori dal contesto locale, ergo non esiste piu' ... ma e' esistito 
Puoi forzare il distruttore dentro il metodo di eccezione errore, cercando sulla GLOBALS ... pero' imho leggermente azzardato ...
codice:
class Test {
private $__phrase;
final function __construct($__phrase = 'none', $forceException = false) {
$this->__phrase = $__phrase;
if($forceException)
$this->throwError();
}
final public function throwError() {
$found = false;
foreach($GLOBALS as $key => &$value)
if($value instanceof Test)
if(!$found)
$found = true;
if(!$found)
$this->__destruct();
throw new Exception('
This is an exception ['.$this.'] .');
}
final function __destruct() {
echo '<hr />'.$this->__phrase;
}
}
// forzare l' eccezione col metodo [ $t prima del try, esiste ]
$t = new Test('destructor will be called ?');
try {
$t->throwError();
}
catch(Exception $e) {
echo $e->getMessage();
}
if($t)
unset($t);
echo '
----------------------------------';
// forzare l' eccezione nel costruttore
// [ $z nel try che non viene eseguito causa eccezione, $z non esiste ]
try {
$z = new Test('destructor will be called in constructor ?', true);
}
catch(Exception $e) {
echo $e->getMessage();
}