Les classes et les objets (PHP 5)
PHP Manual

Late Static Bindings (Résolution statique à la volée)

Depuis PHP 5.3.0, PHP implémente une fonctionnalité appelée late static bindings, en français la résolution statique à la volée, qui est utilisée pour choisir la classe appelée dans le cadre de l'héritage de méthodes statiques.

Cette fonctionnalité a été baptisée "late static bindings", d'un point de vue interne. "Late binding", littéralement compilation tardive, vient du fait que les éléments static:: ne seront plus résolus en utilisant la classe où la méthode a été définie, mais celle qui est active durant l'exécution. L'adjectif statique a été ajouté car ce problème s'applique aux méthodes statiques, mais pas seulement.

Limitations de self::

Les références à la clsse courante, avec self:: ou __CLASS__ sont résolues en utilisant la classe à qui appartiennent les fonctions, où elles ont été définies :

Exemple #1 Utilisation de self::

<?php
class {
    public static function 
qui() {
        echo 
__CLASS__;
    }
    public static function 
test() {
        
self::qui();
    }
}

class 
extends {
    public static function 
qui() {
         echo 
__CLASS__;
    }
}

B::test();
?>

L'exemple ci-dessus va afficher :

A

Utilisation de la résolution statique à la volée

La résolution statique à la volée essaie de dépasser cette limitation en introduisant un mot clé qui fait référence à la classe qui est appelée durant l'exécution. Simplement, ce mot-clé vous permet de faire référence à B depuis test(), dans l'exemple précédent. Il a été décidé de ne pas introduite de nouveau mot clé, mais plutôt d'utiliser le mot static qui était déjà réservé.

Exemple #2 Utilisation simple de static::

<?php
class {
    public static function 
qui() {
        echo 
__CLASS__;
    }
    public static function 
test() {
        static::
qui(); // Ici, résolution à la volée
    
}
}

class 
extends {
    public static function 
qui() {
         echo 
__CLASS__;
    }
}

B::test();
?>

L'exemple ci-dessus va afficher :

B

Note: static:: ne fonctionne pas comme $this pour les méthodes statiques. $this-> suit les règles de l'héritage alors que static:: ne les suit pas. Cette différence est détaillée plus tard dans le manuel.

Exemple #3 Utilisation de static:: dans un contexte non statique

<?php
class TestChild extends TestParent {
    public function 
__construct() {
        static::
qui();
    }

    public function 
test() {
        
$o = new TestParent();
    }

    public static function 
qui() {
        echo 
__CLASS__."\n";
    }
}

class 
TestParent {
    public function 
__construct() {
        static::
qui();
    }

    public static function 
qui() {
        echo 
__CLASS__."\n";
    }
}
$o = new TestChild;
$o->test();

?>

L'exemple ci-dessus va afficher :

TestChild
TestParent

Note: La résolution des statiques à la volée va s'arrêter à un appel statique complètement résolu. D'un autre coté, les appels à statique en utilisant un mot-clé comme parent:: ou self:: va transmettre l'information appelante.

Exemple #4 Appel avec ou sans transmission

<?php
class {
    public static function 
foo() {
        static::
qui();
    }

    public static function 
qui() {
        echo 
__CLASS__."\n";
    }
}

class 
extends {
    public static function 
test() {
        
A::foo();
        
parent::foo();
        
self::foo();
    }

    public static function 
qui() {
        echo 
__CLASS__."\n";
    }
}
class 
extends {
    public static function 
qui() {
        echo 
__CLASS__."\n";
    }
}

C::test();
?>

L'exemple ci-dessus va afficher :

A
C
C

Cas limites

Il y a de nombreuses solutions pour lancer un appel à une méthode en PHP, comme des fonctions de rappels, ou des méthodes magiques. La résolution statique à la volée qui effectue son travail à l'exécution, il peut y avoir des cas particuliers qui donnent des résultats inattendus.

Exemple #5 Résolution statique à la volée dans une méthod magique

<?php
class {

   protected static function 
qui() {
        echo 
__CLASS__."\n";
   }

   public function 
__get($var) {
       return static::
qui();
   }
}

class 
extends {

   protected static function 
qui() {
        echo 
__CLASS__."\n";
   }
}

$b = new B;
$b->foo;
?>

L'exemple ci-dessus va afficher :

B

Les classes et les objets (PHP 5)
PHP Manual