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 classe 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 introduire 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 loin 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 statiques 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�thode 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