begin process at 2010 03 20 19:59:59
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Class et Objet ( POO )

 > ABSTRACTION EN PHP 4

ABSTRACTION EN PHP 4


 Information sur le tutoriel

 Description

Sous PHP 4 on a pas la possibilité de créer des interfaces ou des classes abstraites, ce qui perd un peu l'attrait de la POO. Une astuce dans ce cas ...

Tutorial


L'idée c'est de vous proposer de rationnaliser le développement objet sous PHP 4 au cas où vous n'auriez pas le choix - sinon passez à PHP 5.  
On commence tout d'abord par la définition d'une classe abstraite selon le WIKI :

Classe abstraite

Dans certains langages, une classe peut être partiellement définie. En particulier, certaines méthodes de cette classe n'ont pas de corps ou d'implémentation. Ces méthodes sont dites abstraites (ou virtuelles en C++).
Les classes possédant au moins une méthode abstraite sont aussi dites classes abstraites (ou virtuelles) et ne peuvent pas être instanciées directement -sauf en créant une sous-classe non abstraite.
Exemple : On souhaite modéliser les relations objets d'un dessin vectoriel. On peut dire qu'un objet dessin est un ensemble de géométries (la classe abstraite) et chaque géométrie peut être un point, un polygone ou une ligne brisée (ces trois classes héritent de géométrie). La classe abstraite n'est donc pas indispensable en soi, mais elle est indispensable[1] pour un modèle propre, générique et simplifié.
Le mixin est un cas particulier de classe abstraite. Il permet d'ajouter un service aux sous-classes.

Interface


Une classe ne possédant que des méthodes abstraites est appelée interface ou classe purement virtuelle (en C++) ou protocole (en Objective C).

Du coup, on comprend vite pk en PHP 4 si on veut faire de la POO cela devient indispensable.
La solution - c'est l'héritage et de créer une classe s'appelant abstractClass par exemple : 

            $GLOBALS['abstractClass'] = array();
            class abstractClass {
                        function abstractClass($methods) {
                                   $class_name = get_class($this);
                                   if (isset($GLOBALS['abstractClass'][$class_name])) return true;
                                   foreach($methods as $name => $args) $this->checkMethod($name);
                                   $GLOBALS['abstractClass'][$class_name] = $methods;
                        }
                        function triggerError($description) {
                                   return trigger_error($description, E_USER_ERROR);
                        }
                        function checkMethod($name, $args = NULL) {
                                   if (!method_exists($this, $name)) {
                                               return $this->triggerError('You class '.get_class($this).' must implements '.$name.'('.$args.') function !');
                                   } else return true;
                        }
                        function abstractMethods() {
                                   $class_name = get_class($this);
                                   if (isset($GLOBALS['abstractClass'][$class_name])) {
                                               return $GLOBALS['abstractClass'][$class_name] = $methods;
                                   } else {
                                               return $this->triggerError('abstractMethods is not a static method or '.$class_name.' is not a compliant class !');
                                   }
                        }                      
            }


Lors de la création de votre classe abstraite, faites-la hériter de abstractClass de la manière suivante : 

            class dbConnector extends asbtractClass { 
                        function dbConnector() { 
                                   parent::asbtractClass(array( 
                                               'connect'         => '$user, $pwd, $host', 
                                               'close'            => '', 
                                               'request'          => '$sql' 
                                   )); 
                        } 
            }


 
Lors de la construction de la classe appelez le constructeur de la classe parente en lui spécifiant un tableau composé en indice du nom de la fonction et en valeur de la liste de ses arguments (a titre indicatif).
Voici un exemple concret d'utilisation :  

            class mySqlConnector extends dbConnector { 
                        function connect($user, $pwd, $host) { 
                                   // YOUR CODE 
                        } 
                        function request($sql) { 
                                   // YOUR CODE 
                        } 
                        // VOLUTARY FORGET CLOSE FUNCTION ... 
            }  
            $db = new mySqlConnector(); 
            // OUTPUT ERROR : You class mySqlConnector must implements close() function !  

AVANTAGES :
Vous pouvez avoir un gestionnaire d'erreurs qui vérifiera la conformité des définitions de votre classe concrète.
Votre classe abstraite ne pourra pas être construite directement.
DESAVANTAGES :
La vérification se fait sur la construction de l'objet et non sur la définition de la classe - du coup l'erreur n'est visible que lors de l'instanciation de l'objet.
La vérification dans le constructeur s'effectue à chaque chargement, du coup baisse des perfs surtout si l'objet est chargé une multitude de fois.
CONSEILS :
Méthode à utiliser que sur des classes abstraites qui devront être implémentées par des tiers sinon la vérification n'a pas trop d'importance, on part du principe que vous êtes au point sur votre propre architecture et que vous avez du tps pour débuguer en cas de problème.

 Historique

01 juin 2008 14:13:04 :
Bug Saut de lignes
01 juin 2008 14:22:04 :
Ajout vérif unique sur constructeur

Commentaires

Commentaire de coucou747 le 04/06/2008 04:02:55

pour une classe abstraite, ok ton modele tient... mais pour une interface, absolument pas.
je prends quelques classes au pif parmi mes 900 dernieres lignes php :

class MException extends Exception implements Printable{
class SortItterator implements FinIterator, countable{
class UnixFile implements Sortable, Filtrable, Printable{
class Dossier extends UnixFile implements FinIterator{
class Filterit extends ProxyClass implements Iterator {
class DossierRec extends Dossier implements Recurable{
class Recurit extends ProxyClass implements Iterator{

bon, on va s'arreter la...
t'as pas d'heritage multiple en php, mais par contre, on peut faire de l'interfacage multiple...
on programme objet, sans toujours heriter, mais en implementant...
on ne regarde pas forcement un objet pour ce qu'il est, mais pour son comportement.

Bref, php4 ne PEUT pas simuler ca... upgrade ou pert ton temps...

Commentaire de aKheNathOn le 04/06/2008 23:24:37

Yep, tt à fait d'accord avec toi. A n'utiliser que si on est obligé de rester en PHP 4 sinon upgrade PHP 5.

En plus ce que coucou à oublié de dire c'est qu'en PHP 4 pour simuler cette abstraction on alourdit le traitement vu que c'est pas natif à la base - du coup perte de perf ...

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,078 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales