Categories
class oop php scope

When should I use ‘self’ over ‘$this’?

2173

In PHP 5, what is the difference between using self and $this?

When is each appropriate?

1

1890

Short Answer

Use $this to refer to the current
object. Use self to refer to the
current class. In other words, use
$this->member for non-static members,
use self::$member for static members.

Full Answer

Here is an example of correct usage of $this and self for non-static and static member variables:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

Here is an example of incorrect usage of $this and self for non-static and static member variables:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

Here is an example of polymorphism with $this for member functions:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

Here is an example of suppressing polymorphic behaviour by using self for member functions:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

The idea is that $this->foo() calls the foo() member function of whatever is the exact type of the current object. If the object is of type X, it thus calls X::foo(). If the object is of type Y, it calls Y::foo(). But with self::foo(), X::foo() is always called.

From http://www.phpbuilder.com/board/showthread.php?t=10354489:

By http://board.phpbuilder.com/member.php?145249-laserlight

9

  • 343

    This answer is overly simplistic. As pointed in other answers, self is used with the scope resolution operator :: to refer to the current class; this can be done both in static and non-static contexts. Additionally, it’s perfectly legal to use $this to call static methods (but not to reference fields).

    – Artefacto

    Aug 25, 2010 at 9:04


  • 54

    Also consider using static:: instead of ::self if youre on 5.3+. It may cause you untold headaches otherwise, see my answer below for why.

    – Sqoo

    Oct 6, 2011 at 15:01

  • 25

    -1. This answer is misleading, read the other answers for more info.

    – Pacerier

    Jul 13, 2013 at 9:14


  • 8

    It may be overly simplified, but it answered my basic level question without making my head explode. I did get some more information that I found helpful further down, but for now I was just trying to figure out why I hit my class attributes with $this->attrib and the class constants with self::constant. This helped me understand that better

    – MydKnight

    Jul 12, 2015 at 0:32

  • What about $this::?

    – James

    Dec 21, 2017 at 15:23

761

The keyword self does NOT refer merely to the ‘current class’, at least not in a way that restricts you to static members. Within the context of a non-static member, self also provides a way of bypassing the vtable (see wiki on vtable) for the current object. Just as you can use parent::methodName() to call the parents version of a function, so you can call self::methodName() to call the current classes implementation of a method.

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

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

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

This will output:

Hello, I’m Ludwig the geek
Goodbye from Ludwig the person

sayHello() uses the $this pointer, so the vtable is invoked to call Geek::getTitle().
sayGoodbye() uses self::getTitle(), so the vtable is not used, and Person::getTitle() is called. In both cases, we are dealing with the method of an instantiated object, and have access to the $this pointer within the called functions.

6

  • 3

    This answer would be even better if you started with a general rule rather than an exception. It’s a matter of style, not of technical expertise. This is the best example I’ve ever seen of the difference between self:: and $this->, but it’s a shame to hide that by disproving a notion first.

    – adjwilli

    Sep 26, 2014 at 14:12


  • 3

    @adjwilli: Why is that bad style? Doesn’t it raise consciousness if the expectation (thesis) of the OP is first disapproved (antithesis) and then the explanation is given as synthesis?

    – hakre

    Oct 9, 2014 at 13:39

  • 1

    I find “current class” really problematic. As that word combination can be understood as both “the class where self is located”/”the class definition it is a literal part of” as well as “the object’s class” (which actually would be static).

    – Jakumi

    Sep 12, 2017 at 9:43

  • What about $this::?

    – James

    Dec 21, 2017 at 15:23

  • 1

    @James – there is no good reason to use $this::; all possible cases are already covered by more commonly used syntaxes. Depending on what you mean, use $this->, self::, or static::.

    Oct 7, 2019 at 9:43

482

Do not use self::. Use static::*

There is another aspect of self:: that is worth mentioning. Annoyingly, self:: refers to the scope at the point of definition, not at the point of execution. Consider this simple class with two methods:

class Person
{

    public static function status()
    {
        self::getStatus();
    }

    protected static function getStatus()
    {
           echo "Person is alive";
    }

}

If we call Person::status() we will see “Person is alive” . Now consider what happens when we make a class that inherits from this:

class Deceased extends Person
{

    protected static function getStatus()
    {
           echo "Person is deceased";
    }

}

Calling Deceased::status() we would expect to see “Person is deceased”. However, we see “Person is alive” as the scope contains the original method definition when the call to self::getStatus() was defined.

PHP 5.3 has a solution. The static:: resolution operator implements “late static binding” which is a fancy way of saying that it’s bound to the scope of the class called. Change the line in status() to static::getStatus() and the results are what you would expect. In older versions of PHP you will have to find a kludge to do this.

See PHP Documentation

So to answer the question not as asked…

$this-> refers to the current object (an instance of a class), whereas static:: refers to a class.

8

  • 6

    What about for class constants?

    Apr 11, 2012 at 12:55

  • 59

    “Calling Deceased::status() we would expect to see “Person is deceased””. No. This is a static function call so there is no polymorphism involved.

    – cquezel

    Feb 5, 2013 at 20:08

  • 2

    Of all of PHP’s flaws, I for one don’t think this is crazy at all. How else would they allow coders to designate methods on the current class (as opposed to looking them up in the vtable)? If they had named it differently (perhaps with leading underscores) then people who want this feature would criticize it for being ugly. Else, whatever sane name they might use it seems there would always be easily confused people who would criticize it for being “insane” behavior, likely oblivious to how method dispatch even works.

    – tne

    May 16, 2015 at 10:24

  • 2

    The example seems confusing to me: I see getStatus method as one I would call for a class instance, not for a class.

    Jul 17, 2015 at 12:16

  • 1

    @Sqoo – saying “DO NOT USE self::, use static::” is a strange point to make – those are deliberately not the same operation. I think the point you are really making is “it is clearer if you use the actual class name ‘MyClass::’, rather than ‘self::’. That is, if you want the behavior of self::, you can get that, less confusingly, by using the specific class name, e.g. MyClass::.

    Oct 7, 2019 at 9:47