PHPUnit – Verwenden Sie $this oder self für statische Methoden?

Lesezeit: 4 Minuten

Benutzer-Avatar
Wolfsblvt

Ich möchte keinen langen Text schreiben, weil es eine kurze Frage ist. PHPUnit-Tests enthalten mehrere statische Methoden. Zum Beispiel all die \PHPUnit\Framework\Assert::assert*() Methoden und auch die identicalTo, equalTo.

Meine IDE (mit IntelliSense/Autovervollständigung) akzeptiert keine Anrufe mit $this, aber mit sich selbst. Ich habe gelernt, dass statische Funktionen über die Klasse aufgerufen werden sollten, nicht über ein Objekt self.

Was ist richtiger?

$this->assertTrue('test');

oder

self::assertTrue('test');

?

(Und wenn “$this” richtiger ist, können Sie vielleicht darauf hinweisen, warum wir “self” nicht verwenden sollten?)

  • Das ist eine gute Frage. Ich verstehe auch nicht ganz, warum Methoden statisch sind, aber der gesamte Code, den ich gesehen habe, verwendet $this anstelle von self.

    – Serge Kuharjew

    16. September 2015 um 9:30 Uhr

Benutzer-Avatar
Mike32

Allgemein, self wird nur verwendet, um auf statische Methoden und Eigenschaften zu verweisen (obwohl Sie verwirrenderweise kann beziehen sich auf nichtstatische Methoden mit selfund zu statischen Methoden mit $thisvorausgesetzt, die mit aufgerufenen Methoden self nicht referenzieren $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"

Es ist wichtig, beim Umgang mit Erbschaften daran zu denken $this oder self. $this bezieht sich immer auf das aktuelle Objekt, während self bezieht sich auf die Klasse, in der self wurde benutzt. Modernes PHP enthält auch späte statische Bindung über die static Schlüsselwort, das genauso funktioniert wie (und dem vorgezogen werden sollte) $this für statische Funktionen.

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

Insbesondere in Bezug auf PHPUnit scheinen sie einfach Dinge zu tun so wie sie es immer gemacht haben! Obwohl laut ihrer Dokumentation, Ihr Code sollte gut funktionieren mit statischen Methoden.

  • Das ist eine wirklich gute Antwort. Tut mir leid, dass ich es so spät gesehen habe. Jetzt verstehe ich besser, wie diese Identifikatoren funktionieren. Aber trotzdem verwirrt mich das Konzept. Warum kann man statische Funktionen in PHP so überschreiben, dass sich der Rückgabewert in Childs tatsächlich ändert? Und abgesehen davon, warum das möglich ist, warum verwendet PHPUnit $this-> und nicht das richtige static:: dann zugreifen? Legacy-Code?

    – Wolfsblvt

    17. Mai 2017 um 16:32 Uhr

  • “Statisch” bedeutet nicht, dass es sich nicht ändert, wie im normalen englischen Sprachgebrauch. Es einfach beschreibt, wie es heißt (dh ohne eine Instanz eines Objekts zu benötigen), sodass es kein Problem gibt, sie in untergeordneten Klassen neu zu definieren. Ich bin mit PHPUnit nicht vertraut, aber es sieht so aus, als wäre es einfach die Art, wie sie Dinge tun.

    – Mike32

    17. Mai 2017 um 17:19 Uhr

  • Ich kann mir immer noch nicht vorstellen, wie schmutzig und verwirrend das ist, aber ich denke, so ist PHP einfach. Vielen Dank für Ihre schnelle Antwort. Ich denke, Ihre Antwort in Kombination mit dem Link, den Sie hier angegeben haben, sollte für zukünftige Leser ausreichen. Ich werde das als gelöst markieren.

    – Wolfsblvt

    17. Mai 2017 um 17:50 Uhr

  • OK danke. Ich habe die Antwort aktualisiert, um den Link aus den Kommentaren aufzunehmen.

    – Mike32

    17. Mai 2017 um 18:47 Uhr

Benutzer-Avatar
Benutzer1983686

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);
}

Technisch static::assertTrue() ist richtig, aber die übliche Verwendung der Assert-Methoden ist $this->assertTrue().

  • Aber warum sollten Sie verwenden $this->assertTrue()wenn self::assertTrue() wäre der richtige Weg? Ich verstehe den Sinn darin nicht. Das war der Grund für meine Frage.

    – Wolfsblvt

    23. Oktober 2015 um 7:16 Uhr

Die phpunit-Dokumentation sagt, dass Sie beide verwenden können und befürwortet nicht das eine gegenüber dem anderen. Also wählen Sie!
https://phpunit.readthedocs.io/en/9.2/assertions.html

1122200cookie-checkPHPUnit – Verwenden Sie $this oder self für statische Methoden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy