8795 sujets

Développement web côté serveur, CMS

Bonjour à tous,

Mon problème est simple mais je ne trouve pas la solution. J'aimerai pouvoir supprimer un objet (et donc appeler sa fonction __destruct()) alors que plusieurs référence lui sont rattachées.

J'utilise PHP 5.2.10

Puisqu'un bon bout de code vaux mieux qu'un long discours… si si! Smiley smile

class Object{
	public static $collection;

	protected $internal_uuid;



	public static function factory($uuid = null){
		if(isset(self::$collection[$uuid])){
			return self::$collection[$uuid];
		}else{
			return new Object();
		}
	}

	protected function __construct(){
		$this->uuid();
		/* Bon je vous copie pas tous le code mais en gros cette fonction affecte,
		 * vous l'aurai compris, un identifiant unique a $this->internal_uuid.
		 */

		self::$collection[$this->internal_uuid] = $this;
	}

	public function __destruct(){
		echo '__destruct';
	}
}

	//Après la déclaration de la classe, ben… on s'en sert.
$oObject = Object::factory();
unset($oObject);
echo '*** FIN DU SCRIPT ***';



L'exécution de ce bout de code nous donne :

*** FIN DU SCRIPT ***
__destruct



Ce qui est tout a fait normal car la référence à notre objet se trouve encore dans Object::collection après le unset et c'est donc a la fin de l'exécution du script que l'appel à __destruct se fait.


Ce que j'aimerai donc obtenir c'est :

__destruct
*** FIN DU SCRIPT ***

Avec Object::collection[<identifiant unique de mon instance>] == NULL juste après l'appel de unset($oObject)




Quelqu'un a-t-il une idée ? Je m'arrache les cheveux la dessus… j'ai essayé dans tous les sens avec référence, sans référence (bon même si elles sont implicite en PHP5)
Modifié par bilhackmac (15 Nov 2009 - 17:26)
IL me semble qu'on ne peut pas forcer la destruction d'un objet en php comme on pourrait le faire en C++. LE plus simple est, à mon avis, de mettre simplement toutes ses références à null.
Ce n'est pas possible, j'ai virtuellement une infinitée de références possibles dans tous les contexts imaginables.
Voici la solution :


Ma class

class Object{
	public $uuid;

	private static $collection = array();



	public static function &factory($uuid = null){
		if($uuid != null && isset(self::$collection[$uuid])){
			return self::$collection[$uuid];
		}else{
			$Object = new Object();
			return self::$collection[$Object->uuid];
		}
	}

	protected function __construct(){
		$this->uuid();

		self::$collection[$this->uuid] = $this;
	}

	public function __destruct(){
		echo __METHOD__;
	}

	final protected function uuid(){
		$md5 = md5(uniqid());
		$this->uuid = substr($md5, 0, 8) .'-'. substr($md5, 8, 4) .'-'. substr($md5, 12, 4) .'-'. substr($md5, 16, 4) .'-'. substr($md5, 20, 12);
	}

	public static function delete(Object $Object) {
		self::$collection[$Object->uuid] = null;
	}
}



Puis les tests

$obj1 = &Object::factory();
$obj2 = &Object::factory($obj1->uuid);
$obj3 = &$obj1;

/* Ici que je fasse */
Object::delete($obj1);

/* ou */
Object::delete($obj2);

/* ou encore */
Object::delete($obj3);

/* puis que je fasse des var_dump */
var_dump($obj1);
var_dump($obj2);
var_dump($obj3);


J'obtiendrai toujours :
Object::__destruct()
NULL
NULL
NULL