Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Matthieu Napoli

blog technique

Simuler des classes Friend en PHP

PHP, malgré la sortie de sa version 5.3 cet été, a toujours quelques lacunes. Parmi l'une d'elle, les classes Friend seraient bien utile.

Visiblement, ce n'est pas au programme, car comme il est élégamment expliqué ici, "long ago, we decided against 'friend' declarations".

Le principe de classes Friend consiste à permettre à une classe d'accéder aux attributs et fonctions privées d'une autre. Ceci est par exemple utile quand on veut implémenter une classe Data Mapper qui fait le lien entre une classe du modèle métier et le modèle de données. Pour sauvegarder un objet en base de données (ou le charger), elle a besoin de définir ses attributs, même ceux privés.

Une manière de contourner cette limitation est peu élégante mais relativement efficace : utiliser les méthodes magiques __get, __set et __call de PHP.

Ainsi, si B essaye d'accéder à un attribut privé de A, la méthode A::__get() sera appelée avec comme paramètre le nom de l'attribut demandé. Il est alors nécessaire de savoir qui demande l'accès à cet attribut : est-ce une classe "Friend" ou pas.

Pour cela, on utilise debug_backtrace() (beurk, oui), qui nous permet de connaitre la classe à l'origine de l'appel. Une petite vérification sur le nom de la classe et on renvoie la valeur de l'attribut demandé.

Voici un exemple sur __get et __set :

public function __get($attribut)
{
    // Accès aux variables privées autorisé pour les Data Mapper
    // Note : une variable privée commence par '_'

    if ($attribut[0] == '_') {
        $trace = debug_backtrace();
        if (isset($trace[1]['class'])) {
            $classname = $trace[1]['class'];
            if (strpos($classname, 'Mapper_')) {
                return $this->$attribut;
            }
        }
    }
    // Accès à un attribut non autorisé
    throw new Exception('Accès à un attribut non autorisé ou inexistant : '
                        . get_class() . '::' . $attribut);
}

public function __set($attribut, $valeur)
{
    // Accès aux variables privées autorisé pour les Data Mapper
    // Note : une variable privée commence par '_'

    if ($attribut[0] == '_') {
        $trace = debug_backtrace();
        if (isset($trace[1]['class'])) {
            $classname = $trace[1]['class'];
            if (strpos($classname, 'Mapper_')) {
                return $this->$attribut = $valeur;
            }
        }
    }
    // Accès à un attribut non autorisé
    throw new Exception('Modification d\un attribut non autorisé ou inexistant : '
                        . get_class() . '::' . $attribut);
}

Cet exemple autorise l'accès aux variables privées et protégées de cette classe à n'importe quelle classe contenant "Mapper_" dans son nom (i.e. Data Mapper). Par contre ce code suppose que vous avez nommé vos variables privées en respectant les conventions de nommage PEAR.

Alors, à quand les classes Friend dans PHP ? Le polymorphisme ? Et l'héritage multiple :-) ?

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: vendredi 18 décembre 2009 22:06 par MadMatt
Classé sous :

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Les actualités de la semaine sur c2i.fr (14 mai - 20 mai) par Richard Clark le il y a 4 heures et 53 minutes

- Reactive Extensions : Consommer des services avec Rx Partie 3, les pièges à éviter par Léonard Labat le il y a 13 heures et 58 minutes

- SharePoint Blog Site, problème d’archives par Le Blog (Vert) d'Arnaud JUND le 05-20-2012, 13:09

- Soirée ALT.NET Mai - 3 présentations par #Rui le 05-18-2012, 11:59

- [ #SharePoint 2010][ #SQLServer 2012] AlwaysOn pour SharePoint (2/4) : Configuration (2e partie)… par Le blog de Patrick [MVP SharePoint] le 05-18-2012, 11:31

- Team Foundation Server 11: tous les trésors cachés du site d’équipe par Philess le 05-16-2012, 19:01

- [PowerShell 3] Télécharger et installer la documentation en ligne par Blog de SPBrouillet (Pierrick BROUILLET) le 05-16-2012, 17:36

- [#SharePoint 2010][#SQLServer 2012] AlwaysOn pour SharePoint (1/4) : Configuration (1ère partie)… par Le blog de Patrick [MVP SharePoint] le 05-16-2012, 12:10

- Job Day @MIC Brussels - .Net Developers on Mobile applications par Le Blog (Vert) d'Arnaud JUND le 05-15-2012, 20:26

- [SharePoint 2010] – SharePoint 2010, Windows (Server) 8 et des erreurs IIS sont dans une VM… par Blog de SPBrouillet (Pierrick BROUILLET) le 05-14-2012, 12:10