chiamare un metodo statico all'interno di una classe?


166

come posso chiamare un metodo statico da un altro metodo all'interno della stessa classe?

$this->staticMethod();

o

$this::staticMethod();

13
Potresti essere interessato a questo ( selfvs. $this): stackoverflow.com/questions/151969/php-self-vs-this
Felix Kling

Solo una FYI, il tuo primo esempio è una variabile di istanza che chiama un metodo statico che non è possibile perché un metodo statico fa parte della classe e non è accessibile tramite una variabile di istanza.
joejoeson,

puoi eliminare $ this ora, per favore, non funziona se si usano solo metodi statici e non esiste alcuna istanza.
Malhal,

Risposte:


322

...ma perché? $ this-> staticMethod () funziona anche. Puoi spiegare perché self :: staticMethod () è più corretto (se lo è)?
Ian Dunn,

29
@Ian Dunn In parole povere, $thisesiste solo se un oggetto è stato istanziato e puoi usarlo solo $this->methodall'interno di un oggetto esistente. Se non si dispone di alcun oggetto ma si chiama semplicemente un metodo statico e in tale metodo si desidera chiamare un altro metodo statico nella stessa classe, è necessario utilizzare self::. Quindi, per evitare potenziali errori (e avvertenze rigorose) è meglio usare self.
jeroen,

1
Grazie! In laravel, ho scoperto che stavo accidentalmente chiamando il metodo statico attraverso un controller esteso utilizzando $this, ma il problema non è emerso fino a quando non è stato inserito il codice stage. nessun errore è tornato, il valore era giusto 0. fai attenzione, usaself::
blamb

44

Supponiamo che questa sia la tua classe:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

Dall'interno del foo()metodo, diamo un'occhiata alle diverse opzioni:

$this->staticMethod();

Quindi questo chiama staticMethod()un metodo di istanza, giusto? Non è così. Questo perché il metodo viene dichiarato come public staticl'interprete lo chiamerà come metodo statico, quindi funzionerà come previsto. Si potrebbe sostenere che farlo rende meno ovvio dal codice che sta avvenendo una chiamata di metodo statico.

$this::staticMethod();

Da PHP 5.3 puoi usare $var::method()per significare <class-of-$var>::; questo è abbastanza conveniente, sebbene il caso d'uso sopra riportato sia ancora piuttosto non convenzionale. Questo ci porta al modo più comune di chiamare un metodo statico:

self::staticMethod();

Ora, prima di iniziare a pensare che ::sia l' operatore di chiamata statica, lascia che ti dia un altro esempio:

self::bar();

Questo stamperà baz = 1, il che significa che $this->bar()e self::bar()farà esattamente la stessa cosa; questo perché ::è solo un operatore di risoluzione dell'ambito. E 'lì per fare parent::, self::e static::il lavoro e consentono di accedere a variabili statiche; come viene chiamato un metodo dipende dalla sua firma e da come è stato chiamato il chiamante.

Per vedere tutto questo in azione, vedi questo output di 3v4l.org .


self::bar()sembra fuorviante - è ormai deprecato? (usando self::per chiamare un metodo di istanza piuttosto che un metodo statico).
ToolmakerSteve

@ToolmakerSteve in che modo diresti che è fuorviante?
Ja͢ck,

Logicamente parlando, non c'è niente selfquando si invoca un metodo statico. Per definizione: il metodo statico è richiamabile da qualsiasi luogo e non riceve un parametro "self". Tuttavia, vedo la comodità di quella phpsintassi, in modo che tu non debba scrivere MyClassName::. Sono abituato a linguaggi tipicamente statici, in cui al compilatore devono essere fornite tutte le variabili disponibili nell'ambito corrente, quindi (l'equivalente di) self::può essere omesso. Quindi uno ha detto solo self instanceMethod; nessun motivo per dirlo self staticMethod.
ToolmakerSteve

15

Questa è una risposta molto tardiva, ma aggiunge alcuni dettagli sulle risposte precedenti

Quando si tratta di chiamare metodi statici in PHP da un altro metodo statico sulla stessa classe, è importante distinguere tra selfe il nome della classe.

Prendi ad esempio questo codice:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

L'output di questo codice è:

Classe originale

Classe estesa

Questo perché si selfriferisce alla classe in cui si trova il codice, piuttosto che alla classe del codice da cui viene chiamata.

Se si desidera utilizzare un metodo definito su una classe che eredita la classe originale, è necessario utilizzare qualcosa del tipo:

$class = get_called_class();
$class::function_name(); 

2
Ho trovato questo informativo. Un piccolo sospetto, non direi che le altre risposte siano "fuorvianti". Più preciso nel dire che sono "incompleti"; non affrontano la domanda (non richiesta) di cosa self::succede nel caso (raro) in cui un metodo statico A chiama un altro metodo statico B e B è stato ignorato in una sottoclasse. IMHO, è meno confuso limitare il metodo che sostituisce i metodi di "istanza"; usa quell'abilità con parsimonia a livello statico. Detto in altro modo, i lettori del tuo codice si aspettano che il metodo prevalga sui metodi di istanza (che è l'essenza della codifica OO), ma non di quelli statici.
ToolmakerSteve

1
Molto utile e ha senso che un'estensione della classe non è la classe originale. Pertanto è ovvio che selfnon verrebbero utilizzati in quel caso. Hai dichiarato una classe separata come estensione della prima classe. L'uso selfall'interno della classe estesa farebbe riferimento alla classe estesa. Questo non contraddice le altre risposte, ma sicuramente aiuta a dimostrare la portata di self.
iyrin,

2

Anche nella versione successiva di PHP self::staticMethod();non funzionerà. Emetterà il rigoroso errore standard.

In questo caso, possiamo creare un oggetto della stessa classe e chiamare per oggetto

ecco l'esempio

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}

Si potrebbe farlo, ma se fun1non è facendo uso di self, non è logico per renderlo un metodo di istanza. Il modo corretto di fare questo in php è quello di dichiarare public static function fun1, quindi chiamare specificando la classe: Foo::fun1. Sono certo che è il modo previsto per correggere quel rigoroso errore standard.
ToolmakerSteve
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.