When should I use 'self' over '$this'?
Short Answer
Use
$this
to refer to the current object. Useself
to refer to the current class. In other words, use$this->member
for non-static members, useself::$member
for static members.
Full Answer
Here is an example of correct usage of $this
and self
for non-static and static member variables:
<?phpclass 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:
<?phpclass 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:
<?phpclass 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:
<?phpclass 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 thefoo()
member function of whatever is the exact type of the current object. If the object is oftype X
, it thus callsX::foo()
. If the object is oftype Y
, it callsY::foo()
. But with self::foo(),X::foo()
is always called.
From http://www.phpbuilder.com/board/showthread.php?t=10354489:
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.
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.
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.