Page 1 sur 1

Constructeurs et destructeurs en PHP4

Posté : 20 juin 2007, 11:18
par Genova
Bonjour,
voilà une petite classe que j'ai développé principalement pour le fun et pour mon utilisation personelle, elle permet "d'émuler" les constructeurs / destructeurs de PHP5 en PHP4. C'est à dire que vous pourrez déclarer une classe comme ceci :
class Test extends _model_
{
   function __construct() {}
   function __destruct() {}

   // Le reste des méthodes et tout le tralala
}
tout simplement, et les appels des constructeurs se feront de la même façon en PHP4 (via la classe _model_ que je fourni ci dessous).

Créez donc un fichier model.php contenant le code suivant :
<?php

/*
** Toutes les classes doivent étendre cette classe
*/
class _model_
{
	/*
	** En PHP4, le constructeur a le nom de la classe.
	*/
	function _model_()
	{
		// Destructeur
		register_shutdown_function(array(&$this, '__destruct'));

		// Appel du constructeur PHP5 manuellement en PHP4
		$args = func_get_args();
		call_user_func(array(&$this, '__construct'), $args);
	}

	/*
	** En PHP5, __construct() devient le constructeur prioritaire
	*/
	function __construct()
	{
	}

	/*
	** Destructeur appelé à partir de PHP5.
	*/
	function __destruct()
	{
	}

	/*
	** Affichage intéligent d'un objet, valable uniquement pour PHP5
	*/
	function __toString()
	{
		$str = '<b>Classname :</b> ' . get_class(&$this) . '<br />';
		$str .= '<b>Properties :</b><ul style="margin: 0">';
		foreach ($this AS $property => $value)
		{
			$str .= '<li><b>' . $property . '</b> = <pre style="display: inline">' . var_export($value, TRUE) . '</pre></li>';
		}
		$str .= '</ul>';
		
		return ($str);
	}

	/*
	** Affectation de propriété
	*/
	function _set($property, $value)
	{
		$this->$property = $value;
	}

	/*
	** Valeur d'une propriété
	*/
	function _get($property)
	{
		if (property_exists(&$this, $property))
		{
			return ($this->$property);
		}
		return (NULL);
	}
}

/*
** Implémentation du clonage d'objet en PHP4
*/
if (version_compare(phpversion(), '5.0') < 0)
{
    eval('function clone($object){return($object);}');
}

?>

Voici un petit exemple d'application :
<?php

// A inclure pour utiliser les constructeurs, destructeurs
include('model.php');

// Votre code source
class toto extends _model_
{
	function __construct()
	{
		echo 'CONSTRUCTEUR<br />';
	}

	function foo()
	{
		echo 'BAR<br />';
	}

	function __destruct()
	{
		echo 'DESTRUCTEUR<br />';
	}
}

$toto = new Toto;
$toto->foo();

?>
Qui affichera à l'écran aussi bien en PHP4 qu'en PHP5 :

Code : Tout sélectionner

CONSTRUCTEUR BAR DESTRUCTEUR
---------------

Si vous regardez le code vous remarquez que les destructeurs sont appelés grace à register_shutdown_function(). Pour le cas où cette fonction ne serait pas accessible sur votre serveur, il vous suffit d'appeler __destruct() en bas de vos scripts PHP pour enclencher manuellement la liste de tous les destructeurs.

J'en ai profité pour ajouter quelques méthodes en plus dans _model_ :
__toString() (méthode magique PHP5)
_set() permet d'assigner une propriété, par exemple $obj->_set('titi', 'toto')
_get() permet de récupérer une propriété, par exemple echo $obj->_get('titi')

Il y a aussi l'implémentation du clonage d'objet PHP5 pour PHP4, à utiliser comme ceci :
$copy = clone($obj);

Posté : 20 juin 2007, 11:52
par naholyr
a priori tu peux :
- supprimer tout ce qui est en dehors de ta classe (la variable globale, la fonction, l'appel à register_shutdown_function)
- remplacer ton constructeur deux petites lignes ;)
function _model_() {
    register_shutdown_function(array($this,'__destruct'));
    $this->__construct();
}

Posté : 20 juin 2007, 12:02
par Genova
Effectivement bonne idée, mais juste avant de faire la modification j'ai une question à ce propos : register_shutdown_function() est elle désactivable par les hébergeurs ? (Si oui pour quel motif ?)

Posté : 20 juin 2007, 13:19
par naholyr
Oui elle est désactivable, comme n'importe quelle autre fonction.
par contre je ne connais pas d'hébergeur qui la désactive, et je ne vois pas de raison de le faire puisque cela ne permet aucune liberté particulière.

Posté : 20 juin 2007, 13:49
par Genova
Voilà c'est modifié. J'en ai profité pour ajouter le passage des arguments au constructeur, j'avais oublié de le faire. Concernant le destructeur, le seul défaut c'est qu'il sera appelé à la toute fin du script uniquement pour PHP4, alors qu'un vrai destructeur est appelé lors de la destruction d'un objet (unset() par exemple). Mais bon on peut pas tout avoir ^^