57 votes

Appel d'une méthode non statique avec "::"

Pourquoi puis-je utiliser une méthode non statique avec la syntaxe des méthodes statiques (class :: method)? Est-ce une sorte de configuration?

 class Teste {

    public function fun1() {
        echo 'fun1';
    }
    public static function fun2() {
        echo "static fun2" ;
    }
}

Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method
 

40voto

notJim Points 5142

PHP est très lâche avec des méthodes statiques et non statiques. Une chose que je ne vois pas ici est que si vous appelez une méthode non statique, ns statiquement à partir d'une méthode non statique de la classe C , $this inside ns fera référence à votre instance de C .

 class A 
{
    public function test()
    {
        echo $this->name;
    }
}

class C 
{
     public function q()
     {
         $this->name = 'hello';
         A::test();
     }
}

$c = new C;
$c->q();// prints hello
 

Il s'agit en fait d'une erreur quelconque si vous avez un rapport d'erreur strict, mais pas autrement.

26voto

David Titarenco Points 17148

Il s'agit d'une "bizarrerie" connue de PHP. C'est par conception pour empêcher la rétropropagation pour déterminer si il y a quelque temps nous avons réellement instancié un objet ou non (rappelez-vous, PHP est interprété, non compilé). Cependant, l'accès à tout membre non statique via l'opérateur de résolution de portée via si l'objet n'est pas instancié entraînera une erreur fatale.

Avec l'aimable autorisation de PHP.net:

 class User {
    const GIVEN = 1;  // class constants can't be labeled static nor assigned visibility
    public $a=2;
    public static $b=3;

    public function me(){
        echo "print me";
    }
     public static function you() {
        echo "print you";
    }
}

class myUser extends User {
}

// Are properties and methods instantiated to an object of a class, & are they accessible?
//$object1= new User();        // uncomment this line with each of the following lines individually
//echo $object1->GIVEN . "</br>";        // yields nothing
//echo $object1->GIVE . "</br>";        //  deliberately misnamed, still yields nothing
//echo $object1->User::GIVEN . "</br>";    // yields nothing
//echo $object1->a . "</br>";        // yields 2
//echo $object1->b . "</br>";        // yields nothing
//echo $object1->me() . "</br>";        // yields print me
//echo $object1->you() . "</br>";        // yields print you

// Are  properties and methods instantiated to an object of a child class,  & are accessible?
//$object2= new myUser();        // uncomment this line with each of the following lines individually
//echo $object2->GIVEN . "</br>";        // yields nothing
//echo $object2->a . "</br>";        // yields 2
//echo $object2->b . "</br>";        // yields nothing
//echo $object2->me() . "</br>";        // yields print me
//echo $object2->you() . "</br>";        // yields print you

// Are the properties and methods accessible directly in the class?
//echo User::GIVEN . "</br>";        // yields 1
//echo User::$a . "</br>";            // yields fatal error since it is not static
//echo User::$b . "</br>";            // yields 3
//echo User::me() . "</br>";        // yields print me
//echo User::you() . "</br>";        // yields print you

// Are the properties and methods copied to the child class and are they accessible?
//echo myUser::GIVEN . "</br>";        // yields 1
//echo myUser::$a . "</br>";        // yields fatal error since it is not static
//echo myUser::$b . "</br>";        // yields 3
//echo myUser::me() . "</br>";        // yields print me
//echo myUser::you() . "</br>";        // yields print you
?>
 

18voto

hakre Points 102271

C'est PHP 4 rétro-compatibilité. En PHP 4, vous ne pouviez pas différer entre une méthode de l'objet et de la fonction globale écrite comme une méthode de classe statique. Par conséquent, les deux ont fait le travail.

Cependant, avec les changements dans le modèle objet de PHP 5 - http://php.net/oop5 - le mot-clé static a été introduit.

Et puis depuis PHP 5.1.3 vous bénéficiez d'une véritable norme stricte des avertissements à propos de ceux qui, comme:

Des Normes strictes: Non méthode statique Foo::bar() ne devraient pas être appelée de façon statique

Et/Ou:

Des Normes strictes: Non méthode statique Foo::bar() ne devraient pas être appelée de façon statique, en supposant que $this de contexte incompatible

qui doit être activée pour le développement de votre installation. Donc, c'est simplement la compatibilité en arrière à une époque où la langue ne pouvait pas différer assez donc c'est "défini" au moment de l'exécution.

Aujourd'hui, vous pouvez déjà défini dans le code, mais le code ne fonctionnera pas si vous avez encore l'appeler "mal".

Certains de Démonstration pour déclencher les messages d'erreur et de montrer le changement de comportement sur les différentes versions de PHP: http://3v4l.org/8WRQH

15voto

webbiedave Points 28781

PHP 4 n'a pas eu un mot-clé static (en fonction de la déclaration de contexte), mais encore des méthodes autorisées à être appelée de façon statique avec ::. Cela s'est poursuivi en PHP 5 pour des raisons de compatibilité.

8voto

Jake N Points 6408

Vous pouvez faire cela, mais votre code d'erreur si vous utilisez $this dans la fonction appelée fun1()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X