2011-01-17 11 views
46

Sono un po 'confuso con questa faccenda. Sto progettando una classe ORM che cerca di comportarsi in modo molto simile a ActiveRecord in ruby ​​on rails, ma non è questo il punto.PHP Can static :: replace self ::?

Quello che sto cercando di dire è che la mia classe fa un uso estensivo dell'ereditarietà degli attributi statici, specialmente per la gestione di database e tabelle. La mia domanda è, dovrei usare auto :: affatto?

+0

penso 'static' è l'approccio sbagliato in primo luogo. Sembra (e si prega di correggere se sbagliato) hai appena reso il codice non testabile. – PeeHaa

risposta

94

Devi chiedere a te stesso: "Sto prendendo di mira il problema con l'approccio adeguato?"

self:: e static:: fare due cose diverse. Ad esempio, self:: o __CLASS__ sono riferimenti alla classe corrente, quindi definito in un determinato ambito NON sarà sufficiente la chiamata statica in avanti.

Che cosa succederà in eredità?

class A { 
    public static function className(){ 
     echo __CLASS__; 
    } 

    public static function test(){ 
     self::className(); 
    } 
} 

class B extends A{ 
    public static function className(){ 
     echo __CLASS__; 
    } 
} 

B::test(); 

Questo stamperà

A 

Nell'altra mano con static:: Ha il comportamento previsto

class A { 
    public static function className(){ 
     echo __CLASS__; 
    } 

    public static function test(){ 
     static::className(); 
    } 
} 

class B extends A{ 
    public static function className(){ 
     echo __CLASS__; 
    } 
} 


B::test(); 

Questo stamperà

B 

che si chiama late static binding in PHP 5.3.0. Risolve la limitazione di chiamare la classe che era di riferimento al runtime.

Con questo in mente penso che ora puoi vedere e risolvere il problema in modo adeguato. Se si ereditano diversi membri statici e si richiede l'accesso ai membri padre e figlio, self:: non sarà sufficiente.

+8

Quindi, in pratica, se voglio che le cose si comportino come al solito, come in ogni altra lingua, dovrei invece usare la statica? E poi quando queste cose non contano davvero, potrei anche usare me stesso per la compatibilità. È corretto? – elite5472

+7

Esatto, se vuoi la compatibilità con le versioni precedenti dovrai occuparti di te stesso. Se si desidera accedere ai membri statici in questo modo, è necessario eseguire un metodo statico che avvolge i membri. – DarkThrone

+0

ok, grazie per aver sistemato le cose per me. – elite5472

6

tenta di utilizzare il codice di sotto per vedere la differenza tra e statica:

<?php 
class Parent_{ 
    protected static $x = "parent"; 
    public static function makeTest(){ 
     echo "self => ".self::$x."<br>"; 
     echo "static => ".static::$x;  
    } 
} 

class Child_ extends Parent_{ 
    protected static $x = "child"; 
} 

echo "<h4>using the Parent_ class</h4>"; 
Parent_::makeTest(); 

echo "<br><h4>using the Child_ class</h4>"; 
Child_::makeTest(); 
?> 

e si ottiene questo risultato:

utilizzando la classe PARENT_

  • auto => genitore
  • static => genitore

utilizzando la classe Child_

  • auto => genitore
  • static => bambino