2015-05-04 33 views
14

Nie chcę pisać długiego tekstu, ponieważ jest to krótkie pytanie. Testy PHPUnit zawierają kilka metod, które są statyczne. Na przykład wszystkie te \PHPUnit\Framework\Assert::assert*() methods, a także identicalTo, equalTo.

Moje IDE (z IntelliSense/autouzupełnianie) nie przyjmuje połączeń z $this, ale z własnym. Nauczyłem się, że funkcje statyczne powinny być wywoływane przez klasę, a nie obiekt, czyli self.

Co jest bardziej poprawne?

$this->assertTrue('test'); 

lub

self::assertTrue('test'); 

?

(A jeśli "$ to" jest bardziej poprawna, można może wskazać, dlaczego nie powinno się używać "ja"?)

+0

To jest dobre pytanie. Nie w pełni rozumiem, dlaczego metody są statyczne, ale cały kod, który widziałem, używa $ this zamiast self. –

Odpowiedz

3

Generalnie self jest stosowany tylko w odniesieniu do metod i właściwości statycznych (choć łudząco ty może odnoszą się do metod non-statyczne z self oraz metod statycznych z $this, pod warunkiem metod zwanych z self nie odwoływać $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" 

Dziedziczenie jest ważne, aby pamiętać, gdy ma do czynienia z $this lub self. $this będzie zawsze odnosić się do bieżącego obiektu, podczas gdy self odnosi się do klasy, w której użyto self. Współczesne PHP zawiera także late static binding za pomocą słowa kluczowego static, które będzie działać w taki sam sposób, jak (i ​​powinno być preferowane powyżej) $this dla funkcji statycznych.

<?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" 

Odnośnie PHPUnit w szczególności, wydaje się po prostu robić rzeczy the way they've always done them! Chociaż zgodnie z ich dokumentacją, używają metod statycznych.

+0

To naprawdę dobra odpowiedź. Przepraszam, że widziałem to tak późno. Teraz lepiej rozumiem, jak działają te identyfikatory. Ale koncepcja jest dla mnie myląca. Dlaczego można nadpisywać funkcje statyczne w PHP, aby zwracana wartość rzeczywiście zmieniała się w elementach potomnych? A poza tym dlaczego jest to możliwe, dlaczego PHPUnit używa '$ this->', a nie poprawny dostęp 'static ::'? Starszy kod? – Wolfsblvt

+0

"Statyczny" nie oznacza, że ​​jest niezmienny, jak w zwykłym angielskim używaniu. Po prostu [opisuje jak to się nazywa] (https://en.wikipedia.org/wiki/Method_ (computer_programming) #Static_methods) (tzn. Bez potrzeby instancji obiektu), więc nie ma problemu z przedefiniowaniem ich w klasach potomnych.Nie znam PHPUnit, ale wygląda na to, że to po prostu [sposób, w jaki robią różne rzeczy] (https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.static-vs- metody niestatycznego użycia asercji). – miken32

+0

Nadal nie mogę zawinąć głowy, jak brudne i mylące jest to, ale myślę, że to po prostu jak PHP jest. Dziękuję za szybką odpowiedź, więc twoja odpowiedź w połączeniu z linkiem podanym tutaj powinna być wystarczającą informacją dla przyszłych czytelników. Zaznaczę to jako rozwiązane. – 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); 
} 

Technicznie static::assertTrue() jest poprawna, ale powszechne stosowanie metod assert to $this->assertTrue().

+2

Ale dlaczego powinieneś użyć '$ this-> assertTrue()', czy 'self :: assertTrue()' byłoby bardziej poprawną metodą? Nie rozumiem sensu tego. To był powód mojego pytania. – Wolfsblvt

+6

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