When should I use 'self' over '$this'? When should I use 'self' over '$this'? php php

When should I use 'self' over '$this'?


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:

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


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.

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.