Подтвердить что ты не робот

PHPUnit - использовать $this или self для статических методов?

Я не хочу писать длинный текст, потому что это короткий вопрос. Тесты PHPUnit содержат несколько статических методов. Например, все \PHPUnit\Framework\Assert::assert*() методы, а также identicalTo, equalTo.

Моя IDE (с IntelliSense/autocompletion) не принимает вызовы с $this, но с self. Я узнал, что статические функции должны вызываться через класс, а не объект, поэтому self.

Что более верно?

$this->assertTrue('test');

или

self::assertTrue('test');

?

(И если "$ this" вернее, можете ли вы указать, почему мы не должны использовать "я"?)

4b9b3361

Ответ 1

Как правило, self используется только для обозначения статических методов и свойств (хотя смутно можно ссылаться на нестатические методы с помощью self и на статические методы с помощью $this, при условии, что методы, вызываемые с помощью self не ссылаются на $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"

Наследование важно помнить при работе с $this или self. $this всегда будет ссылаться на текущий объект, а self - класс, в котором использовался self. Современный PHP также включает позднюю статическую привязку через ключевое слово static, которое будет работать так же, как (и должно быть предпочтительнее) $this для статических функций.

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

Что касается PHPUnit в частности, кажется, что они просто делают вещи то, как они всегда их выполняли! Хотя, согласно их документации, ваш код должен работать нормально, используя статические методы.

Ответ 2

PHPUnit 4.8.9: поставщик /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);
}

Технически static::assertTrue() является правильным, но обычное использование методов assert - $this->assertTrue().