2015-05-04 16 views
14

Non voglio scrivere un lungo testo, perché è una domanda breve. I test PHPUnit contengono diversi metodi statici. Ad esempio tutti quelli \PHPUnit\Framework\Assert::assert*() methods e anche lo identicalTo, equalTo.

Il mio IDE (con IntelliSense/autocompleto) non accetta chiamate con $this, ma con self. Ho imparato che le funzioni statiche dovrebbero essere chiamate attraverso la classe, non un oggetto, quindi self.

Cosa c'è di più corretto?

$this->assertTrue('test'); 

o

self::assertTrue('test'); 

?

(E se "$ questo" è più corretto, si può forse notare per cui non dovremmo usare "sé"?)

+0

Questa è una buona domanda. Inoltre, non capisco appieno perché i metodi siano statici, ma tutto il codice che ho visto usa $ this invece di self. –

risposta

3

Generalmente, self viene utilizzato solo per fare riferimento a metodi e proprietà statiche (anche se fuorviante si possibile riferimento a metodi non statici con self, ea metodi statici con $this, purché i metodi chiamati con self non menzionare $this.)

<?php 
class Test { 
    public static function staticFunc() {echo "static ";} 
    public function nonStaticFunc() {echo "non-static\n";} 
    public function selfCaller() {self::staticFunc(); self::nonStaticFunc();} 
    public function thisCaller() {$this->staticFunc(); $this->nonStaticFunc();} 
} 
$t = new Test; 
$t->selfCaller(); // returns "static non-static" 
$t->thisCaller(); // also returns "static non-static" 

ereditarietà è importante da ricordare quando si tratta di $this o self. $this farà sempre riferimento all'oggetto corrente, mentre self si riferisce alla classe in cui è stato utilizzato self. Modern PHP include anche late static binding tramite la parola chiave static, che funzionerà allo stesso modo di (e dovrebbe essere preferito sopra) $this per le funzioni statiche.

<?php 
class Person { 
    public static function whatAmI() {return "Human";}  
    public function saySelf() {printf("I am %s\n", self::whatAmI());} 
    public function sayThis() {printf("I am %s\n", $this->whatAmI());} 
    public function sayStatic() {printf("I am %s\n", static::whatAmI());} 
} 

class Male extends Person { 
    public static function whatAmI() {return "Male";} 
} 

$p = new Male; 
$p->saySelf(); // returns "I am Human" 
$p->sayThis(); // returns "I am Male" 
$p->sayStatic(); // returns "I am Male" 

Per quanto riguarda PHPUnit in particolare, sembra che semplicemente fanno cose the way they've always done them! Sebbene secondo la loro documentazione, your code should work fine utilizza metodi statici.

+0

Questa è davvero una buona risposta. Mi dispiace di averlo visto così tardi. Ora capisco di più come funzionano quegli identificatori. Ma ancora, il concetto mi confonde. Perché è possibile sovrascrivere le funzioni statiche in PHP in modo che il valore di ritorno cambi in realtà in childs? E inoltre perché è possibile, perché PHPUnit usa '$ this->' e non l'accesso 'statico ::' corretto allora? Codice legacy? – Wolfsblvt

+0

"Statico" non significa che è immutabile, come nel normale utilizzo in inglese. Semplicemente [descrive come viene chiamato] (https://en.wikipedia.org/wiki/Method_ (computer_programming) #Static_methods) (cioè senza bisogno di un'istanza di un oggetto) quindi non c'è alcun problema a ridefinirli nelle classi figlie.Non ho familiarità con PHPUnit, ma sembra che sia solo [il modo in cui fanno le cose] (https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.static-vs- non statico-utilizzo-di-affermazione, metodi). – miken32

+0

Non riesco ancora a spiegarmi quanto sia sporco e confuso, ma immagino sia semplicemente il modo in cui PHP è. Grazie per la tua risposta rapida, credo che la tua risposta combinata con il link che hai fornito qui dovrebbe essere abbastanza informazioni per i futuri lettori. Segnalo come risolto. – Wolfsblvt

2

PHPUnit 4.8.9: vendor/phpunit/phpunit/src/Framework/Assert.php:

/** 
* Asserts that a condition is true. 
* 
* @param bool $condition 
* @param string $message 
* 
* @throws PHPUnit_Framework_AssertionFailedError 
*/ 
public static function assertTrue($condition, $message = '') 
{ 
    self::assertThat($condition, self::isTrue(), $message); 
} 

Tecnicamente static::assertTrue() è corretto, ma il l'uso comune dei metodi di asserzione è $this->assertTrue().

+2

Ma perché dovresti usare '$ this-> assertTrue()', se 'self :: assertTrue()' sarebbe il modo più corretto? Non capisco il punto in questo. Questa è stata la ragione della mia domanda. – Wolfsblvt

+6

https://github.com/sebastianbergmann/phpunit/issues/1914 – user1983686