1

I've read this answer:

Is destructor in PHP predictable?

But still fail to be 100% confident that the destructor is called as soon as the object goes out of scope.

My use case is the following:

class Transaction
{
    private $isComplete = false;

    public function commit() {
        // ...

        $this->isComplete = true;
    }

    public function rollBack() {
        // ...

        $this->isComplete = true;
    }

    public function __destruct() {
        if (! $this->isComplete) {
            $this->rollBack();
        }
    }
}

Say I'm using it this way:

function doSomething() {
    $tx = $this->txManager->beginTransaction();

    // ... code here may or may not throw an exception

    $tx->commit();
}

Can I be 100% confident that in all cases (exception or not), the destructor will be the first thing that will be called as soon as the function ends?

My initial testing shows that yes, exception or not, the destructor is called right away. But I'd like a confirmation, and above all, a pointer to the relevant documentation.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • 1
    Have you read the [PHP documentation about constructors and destructors](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor)? That is the most relevant documentation you can get (apart from the PHP's source code) and it says: _"The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence."_ – axiac Nov 03 '20 at 10:27
  • It is (almost) like in `C++` guaranteed to be called, while in `Java` the objects are Garbage-collected and there is no guarantee for destructor to be ever called. – Top-Master Nov 03 '20 at 10:27
  • As long as it is a simple exception (not some crash caused by *PHP extensions*), **Yes**, the destructor is guaranteed to be called as soon as the object goes out of scope (which is the case if the object scope was the function and there is no reference to it elsewhere). – Top-Master Nov 03 '20 at 10:35

3 Answers3

1

From https://www.php.net/manual/en/language.oop5.decon.php#object.destruct

The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.


In your case it would happen when there is no more reference to $tx anywhere. This would be as soon as we are done with doSomething(), except if there is for example another reference stored in txManager.

  • Coming back to this question I don't know if putting the rollback in the destructor is your best approach. From the documentation it is called "in any order during the shutdown sequence". Meaning it can also be called AFTER the database connection is closed. I wouldn't rely on doing this kind of stuff in the destructor. – Thomas van den Bulk Nov 03 '20 at 10:35
  • Thank you, I've read this page alright but it somehow didn't convince me. Good point on the database connection being closed during the shutdown sequence, I guess some extra checks would be required to avoid making a mess. Doing the rollback in the destructor, though, avoids having to remember to put a big `try/catch` around the whole transactional stuff. – BenMorel Nov 03 '20 at 10:45
  • @Benjamin Another way you could do is by passing a transaction function as argument. Then you can wrap executing that argument-function with a try catch where you commit or roll back. And in the catch function you just throw the exception again to cascade it back upwards. A pseudo example: https://hastebin.com/utenovitar.php – Thomas van den Bulk Nov 03 '20 at 11:06
  • That's exactly what I'm doing at the moment, but I'm finding it cumbersome because I have to bind many variables to the closure every time! – BenMorel Nov 03 '20 at 12:53
  • Yeah I can see how that can become quite annoying over time – Thomas van den Bulk Nov 03 '20 at 13:29
1

A destructor is called when the object is destructed or the script is stopped or exited. If you create a __destruct() function, PHP will automatically call this function at the end of the script.

DEMO

norcal johnny
  • 2,050
  • 2
  • 13
  • 17
-2

you can use register_shutdown_function works when PHP code finished ...


<?php
function shutdown()
{
    // This is our shutdown function, in 
    // here we can do any last operations
    // before the script is complete.

    echo 'Script executed with success', PHP_EOL;
}

register_shutdown_function('shutdown');

also __desctruct method is a magic method, that method auto works when an object remove from memory no need call it

dılo sürücü
  • 3,821
  • 1
  • 26
  • 28