Re: In a destructor, how to detect if an exception is currently in flight?
| From: | Johannes Schlüter | Date: | Wed, 28 Oct 2015 23:17:54 +0000 |
| Subject: | Re: In a destructor, how to detect if an exception is currently in flight? | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-88977@lists.php.net to get a copy of this message | ||
On Wed, 2015-10-28 at 16:02 +0100, Erik van Velzen wrote:
> I didn't see how it could be generalized but your example clears that up.
Quick attempt of a generalization:
abstract class AbstractRAIIGuard {
private $succeeded = false;
protected abstract function fail();
protected function success() {}
public function succeed() {
if (!$this->succeeded) {
throw new RAIIAlreadyMarkedAsSuccessfulException();
}
$this->success();
$this->succeeded = true;
}
public function __destruct() {
if (!$this->succeeded) {
$this->fail();
}
}
}
class CallbackRAIIGuard extends AbstractRAIIGuard {
private $success;
private $fail;
public __construct(callable $fail, callable $success = null) {
$this->success = $success;
$this->fail = $fail;
}
protected function fail() {
call_user_func($this->fail());
}
public function success () {
if ($this->success) {
call_user_func_array($this->success, func_get_args());
}
}
}
class DBRAII extends AbstractRAII {
private $db;
public function __construct(DB $db) {
$this->db = $db;
$db->begin();
}
protected function fail() {
$this->db->rollback();
}
public function success () {
$this->db->commit();
}
}
function foo(DB $db) {
$guard = new DBRAII($db);
// or using the more generic class
$guard = new CallbackRAIIGuard(
[$db, "rollback"], [$db, "commit"]
);
// ....
$guard->succeed();
}
johannes
Attachment: [application/pgp-signature] This is a digitally signed message part signature.asc
Attachment: [application/pgp-signature] This is a digitally signed message part signature.asc