php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53699 After destructor execution, object exists
Submitted: 2011-01-08 15:59 UTC Modified: 2015-04-16 18:59 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: hausner15 at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: Class/Object related
PHP Version: Irrelevant OS: *
Private report: No CVE-ID: None
 [2011-01-08 15:59 UTC] hausner15 at gmail dot com
Description:
------------
I think, in this example after destructor executing, object shouldn`t exist. But result of this code tells something else...

Test script:
---------------
<?php

class A {
	protected $var;

	private static $instance = NULL;
	public static function getInstance() {
		if (is_null(self::$instance))
			self::$instance = new A();

		return self::$instance;
	}

	protected function __construct() {
		echo "creating instance of A\n";
		$this->var = "existing var in instance of A \n";
	}

	public function show() {
		echo $this->var;
	}

	public function __destruct() {
		echo "deleting instance of A\n";
	}
}

class B {
	private static $instance = NULL;
	public static function getInstance() {
		if (is_null(self::$instance))
			self::$instance = new B();

		return self::$instance;
	}

	protected function __construct() {
		echo "creating instance of B\n";
	}

	public function __destruct() {
		A::getInstance()->show();
		echo "deleting instance of B\n";
	}
}


header('Content-type: text/plain');
A::getInstance()->show();
B::getInstance();

?>

Expected result:
----------------
Some error?

Actual result:
--------------
creating instance of A
existing var in instance of A 
creating instance of B
deleting instance of A
existing var in instance of A 
deleting instance of B

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-08 23:53 UTC] cmbecker69 at gmx dot de
Actually, executing the destructor doesn't destroy the object, but
rather the destructor is called by the PHP engine before the
object is destroyed (i.e. its memory is released). However, PHP
makes no guarantee that the destructor is called *immediately*
before destroying the object.

Consider the following script with a cyclic reference between $a
and $b:

    <?php
    
    class A {
        function __destruct() {
            $this->b->tell();
        }
        function tell() {
            echo "I'm an instance of A\n";
        }
    }
    
    class B {
        function __destruct() {
            $this->a->tell();
        }
        function tell() {
            echo "I'm an instance of B\n";
        }
    }
    
    $a = new A();
    $b = new B();
    $a->b = $b;
    $b->a = $a;

Neither object can't be destroyed as long as the other is alive.
To be able to fulfill the contract that all destructors are
called, the engine has to call both destructors first, and only
then can destroy both objects.

Even if there is no cyclic reference, as in the test script of the
OP, detecting that during the shutdown sequence is expensive (if
possible at all), so the engine calls all destructors (in
undefined order[1]), before destroying the objects.

So, IMHO, this is not a bug, but rather a WONTFIX.

[1] <http://php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor>
 [2015-04-16 18:59 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2015-04-16 18:59 UTC] cmb@php.net
Sorry, but your problem does not imply a bug in PHP itself, as
explained in the comment above.

Thank you for your interest in PHP.
 
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Tue Mar 28 21:03:37 2023 UTC