As David said: you'll need to call exit() inside a destructor to stop it.
If however you just want to halt the visual output caused by these destructors but not any other side-effects (file closing, database connection closing) they might do, then it's best to just kill the further output but leave the destructors alone. Which in my opinion would be the route to take since destructors tend to be there for one important reason: cleaning up.
you can do that by manipulating buffered output:
<?php
class Tester{
public function devNull($string){
return "";
}
public function runAndBreak(){
print "run" . PHP_EOL;
// if any output buffer is working, flush it and close it
if(ob_get_level()) ob_end_flush();
// redirect new buffer to our devNull
ob_start(array($this,'devNull'));
exit();
print "still running";
}
function __destruct(){
print "destructor" . PHP_EOL;
}
}
$t = new Tester();
$t->runAndBreak();
this will only print run
and not what's in the destructor. It's done by giving your own callback routine to ob_start that handles and then returns the output. In our case here we simply discard it by returning an empty string.