self или $this в PHP: когда и что использовать? Полный гайд

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Когда использовать self, а когда $this? Разбираемся раз и навсегда

Если вы когда-нибудь писали на PHP в объектно-ориентированном стиле, то наверняка сталкивались с вопросом: «А что, собственно, выбрать — self или $this?». Этот вопрос настолько популярен, что на Stack Overflow он собрал десятки тысяч просмотров и сотни комментариев. И это не случайно: разница между ними — одна из тех «мелочей», которая может превратить ваш код в работающий, но неочевидный, или в элегантный и понятный.

Давайте сразу договоримся: это не взаимозаменяемые вещи. У них разная философия и, что важнее, разное поведение при наследовании. Если вы используете $this там, где нужно self, или наоборот — вы рискуете получить логические ошибки, которые сложно отловить.

В этой статье мы разложим всё по полочкам: от базы до продвинутых сценариев. Поехали!


Короткий ответ (для тех, кто спешит)

Если вы хотите запомнить только одно правило, запомните это:

  • $this-> — для обращения к свойствам и методам экземпляра (объекта). Работает только внутри нестатического контекста.
  • self:: — для обращения к статическим свойствам и методам класса. Работает как в статическом, так и в нестатическом контексте.
  • static:: — «позднее статическое связывание» (Late Static Binding). Используется, когда нужно, чтобы дочерний класс переопределил поведение родителя.

Но дьявол, как всегда, кроется в деталях. Давайте углубимся.

Что такое $this?

$this — это псевдопеременная, которая ссылается на текущий объект. Она доступна только внутри методов класса (не статических) и указывает на тот самый экземпляр, с которым вы работаете.

<?php

class User {
    public string $name;

    public function setName(string $name): void {
        $this->name = $name; // обращаемся к свойству текущего объекта
    }

    public function getName(): string {
        return $this->name;
    }
}

$user = new User();
$user->setName('Анна');
echo $user->getName(); // Анна

Всё просто: $this->name — это «возьми свойство name у того самого объекта, который вызвал этот метод».

Что такое self?

self — это ссылка на текущий класс, а не на объект. Он используется для доступа к статическим членам класса (свойствам и методам, объявленным с ключевым словом static).

<?php

class Config {
    public static string $appName = 'PythonLib';

    public static function getAppName(): string {
        return self::$appName; // обращаемся к статическому свойству класса
    }
}

echo Config::getAppName(); // PythonLib

Обратите внимание: self всегда ссылается на тот класс, в котором он написан. Даже если вы создадите наследника, self в родительском классе продолжит указывать на родителя. Это важнейшее отличие от static.

Главное отличие: self vs $this при наследовании

Вот здесь начинается самое интересное. Представьте, что у вас есть базовый класс Animal и дочерний класс Dog.

<?php

class Animal {
    public static function whoAmI(): string {
        return 'Я — животное';
    }

    public function say(): string {
        // Используем self — он привязан к классу Animal
        return self::whoAmI();
    }
}

class Dog extends Animal {
    public static function whoAmI(): string {
        return 'Я — собака';
    }
}

$dog = new Dog();
echo $dog->say(); // Я — животное

Удивились? Метод say() вызван у объекта класса Dog, но self::whoAmI() внутри него всё равно вызвал метод класса Animal. Почему? Потому что self резолвится на этапе компиляции, а не выполнения. Он «зашит» в тот класс, где написан.

Если же мы хотим, чтобы при вызове метода say() у собаки вызывался именно её метод whoAmI(), нужно использовать static:

<?php

class Animal {
    public static function whoAmI(): string {
        return 'Я — животное';
    }

    public function say(): string {
        // Используем static — он будет резолвиться во время выполнения
        return static::whoAmI();
    }
}

class Dog extends Animal {
    public static function whoAmI(): string {
        return 'Я — собака';
    }
}

$dog = new Dog();
echo $dog->say(); // Я — собака

Это и есть позднее статическое связывание (Late Static Binding), появившееся в PHP 5.3. Оно позволяет «унаследовать» статический контекст.

Когда использовать $this?

Используйте $this, когда:

  • Вы обращаетесь к нестатическим свойствам объекта ($this->name, $this->age).
  • Вы вызываете нестатические методы того же объекта ($this->calculate()).
  • Вы находитесь внутри нестатического метода и хотите передать текущий объект в другой метод ($this->sendEmail($this)).

Главное правило: $this — это про конкретный экземпляр.

Когда использовать self?

Используйте self, когда:

  • Вы обращаетесь к статическим свойствам класса (self::$counter).
  • Вы вызываете статические методы того же класса (self::validate()).
  • Вы находитесь внутри статического метода — $this там вообще недоступен.
  • Вы хотите явно указать, что метод или свойство принадлежат именно этому классу, а не наследнику (чтобы избежать неожиданного переопределения).

Когда использовать static?

static:: — это ваш выбор, когда:

  • Вы пишете код в родительском классе и хотите, чтобы дочерние классы могли его переопределить.
  • Вы используете паттерн Factory Method или Singleton с наследованием.
  • Вы работаете с трейтами и хотите, чтобы метод трейта вызывал переопределённый метод в классе, который использует трейт.
<?php

trait                

Блоги

Рекомендаций по книгам