When should I use 'self' over '$this'?
Asked Answered
S

24

2225

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

When is each appropriate?

Selby answered 30/9, 2008 at 6:23 Comment(0)
N
1929

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

Nympho answered 30/9, 2008 at 6:29 Comment(10)
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).Siusan
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.Gon
-1. This answer is misleading, read the other answers for more info.Aggression
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 betterSystole
What about $this::?Tessy
@Tessy That's how you call a static method. Like staticclass::parse(). But, like yours, having $ in your class name is not valid.Burge
WARNING: "use $this->member for non-static members" this does not apply to const MYCONST = 1 defined in non-static classes. Calling $this->MYCONST will trigger an undefined property notice. The only way to get such value declared inside a non-static (or static) class is to use self::MYCONST.Fourlegged
Both links are broken: "The page you requested could not be found. Return to PHPBuilder Forums"Uncinus
It would be nice to see the output of each example, to give a better overview on what's happening.Outgrow
what does something like this mean? function ($lines, self $languageLine) use ($group, $locale) { .. }Rocha
P
765

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.

Potentilla answered 27/7, 2009 at 18:0 Comment(6)
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.Inharmonious
@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?Carlsen
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).Countermove
What about $this::?Tessy
@Tessy - 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::.Cudlip
@Cudlip Fair enough. I just wondered if there was a good use case, or just another pointless thing in PHP with too much wiggle room etc. It is confusing at first but would surely mean self due to the colons.Tessy
G
491

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.

Gon answered 24/7, 2011 at 15:8 Comment(8)
What about for class constants?Cantor
"Calling Deceased::status() we would expect to see "Person is deceased"". No. This is a static function call so there is no polymorphism involved.Sankhya
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.Broaddus
The example seems confusing to me: I see getStatus method as one I would call for a class instance, not for a class.Tildie
Please consider editing the answer as php -r "class X { private const X = 1; public static function show() { echo static::X; }} class Y extends X {} Y::show();" will throw undefined class constant X since constant does not exist in Y. in this case, self::X is required (instead of making const protected which one might sadly do if they consider self:: as forbidden).Bifilar
@Gon - 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::.Cudlip
@Cudlip "those are deliberately not the same operation" Deliberately? It looks like in 5.2 the PHP folks finally realized that self is an aberration and created static, then they had to keep self for compatibility. Thus we have two similar features from two different keywords ; that just induces confusion. self indeed has some special uses, but, really, is not worth it.Unavoidable
@Breakingnotsobad - I agree. Most notably, "self" is a terrible choice of names, given how it behaves inside static methods. Especially given how other OO languages use the term. If php didn't have the ..unusual.. notion of tracking "last non-forwarding" class, then Rasmus would have had to do a more traditional approach, instead of re-using "self" to mean "class the static method is defined in". Arguably, the result would be non-aberrant; __CLASS__ already has that meaning, so you don't have to type the name of the class you are in, so valid if copy/pasted to a different class.Cudlip
P
270

To really understand what we're talking about when we talk about self versus $this, we need to actually dig into what's going on at a conceptual and a practical level. I don't really feel any of the answers do this appropriately, so here's my attempt.

Let's start off by talking about what a class and an object is.

Classes And Objects, Conceptually

So, what is a class? A lot of people define it as a blueprint or a template for an object. In fact, you can read more About Classes In PHP Here. And to some extent that's what it really is. Let's look at a class:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

As you can tell, there is a property on that class called $name and a method (function) called sayHello().

It's very important to note that the class is a static structure. Which means that the class Person, once defined, is always the same everywhere you look at it.

An object on the other hand is what's called an instance of a Class. What that means is that we take the "blueprint" of the class, and use it to make a dynamic copy. This copy is now specifically tied to the variable it's stored in. Therefore, any changes to an instance is local to that instance.

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

We create new instances of a class using the new operator.

Therefore, we say that a Class is a global structure, and an Object is a local structure. Don't worry about that funny -> syntax, we're going to go into that in a little bit.

One other thing we should talk about, is that we can check if an instance is an instanceof a particular class: $bob instanceof Person which returns a boolean if the $bob instance was made using the Person class, or a child of Person.

Defining State

So let's dig a bit into what a class actually contains. There are 5 types of "things" that a class contains:

  1. Properties - Think of these as variables that each instance will contain.

    class Foo {
        public $bar = 1;
    }
    
  2. Static Properties - Think of these as variables that are shared at the class level. Meaning that they are never copied by each instance.

    class Foo {
        public static $bar = 1;
    }
    
  3. Methods - These are functions which each instance will contain (and operate on instances).

    class Foo {
        public function bar() {}
    }
    
  4. Static Methods - These are functions which are shared across the entire class. They do not operate on instances, but instead on the static properties only.

    class Foo {
        public static function bar() {}
    }
    
  5. Constants - Class resolved constants. Not going any deeper here, but adding for completeness:

    class Foo {
        const BAR = 1;
    }
    

So basically, we're storing information on the class and object container using "hints" about static which identify whether the information is shared (and hence static) or not (and hence dynamic).

State and Methods

Inside of a method, an object's instance is represented by the $this variable. The current state of that object is there, and mutating (changing) any property will result in a change to that instance (but not others).

If a method is called statically, the $this variable is not defined. This is because there's no instance associated with a static call.

The interesting thing here is how static calls are made. So let's talk about how we access the state:

Accessing State

So now that we have stored that state, we need to access it. This can get a bit tricky (or way more than a bit), so let's split this into two viewpoints: from outside of an instance/class (say from a normal function call, or from the global scope), and inside of an instance/class (from within a method on the object).

From Outside Of An Instance/Class

From the outside of an instance/class, our rules are quite simple and predictable. We have two operators, and each tells us immediately if we're dealing with an instance or a class static:

  • -> - object-operator - This is always used when we're accessing an instance.

    $bob = new Person;
    echo $bob->name;
    

    It's important to note that calling Person->foo does not make sense (since Person is a class, not an instance). Therefore, that is a parse error.

  • :: - scope-resolution-operator - This is always used to access a Class static property or method.

    echo Foo::bar()
    

    Additionally, we can call a static method on an object in the same way:

    echo $foo::bar()
    

    It's extremely important to note that when we do this from outside, the object's instance is hidden from the bar() method. Meaning that it's the exact same as running:

    $class = get_class($foo);
    $class::bar();
    

Therefore, $this is not defined in the static call.

From Inside Of An Instance/Class

Things change a bit here. The same operators are used, but their meaning becomes significantly blurred.

The object-operator -> is still used to make calls to the object's instance state.

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

Calling the bar() method on $foo (an instance of Foo) using the object-operator: $foo->bar() will result in the instance's version of $a.

So that's how we expect.

The meaning of the :: operator though changes. It depends on the context of the call to the current function:

  • Within a static context

    Within a static context, any calls made using :: will also be static. Let's look at an example:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }
    

    Calling Foo::bar() will call the baz() method statically, and hence $this will not be populated. It's worth noting that in recent versions of PHP (5.3+) this will trigger an E_STRICT error, because we're calling non-static methods statically.

  • Within an instance context

    Within an instance context on the other hand, calls made using :: depend on the receiver of the call (the method we're calling). If the method is defined as static, then it will use a static call. If it's not, it will forward the instance information.

    So, looking at the above code, calling $foo->bar() will return true, since the "static" call happens inside of an instance context.

Make sense? Didn't think so. It's confusing.

Short-Cut Keywords

Because tying everything together using class names is rather dirty, PHP provides 3 basic "shortcut" keywords to make scope resolving easier.

  • self - This refers to the current class name. So self::baz() is the same as Foo::baz() within the Foo class (any method on it).

  • parent - This refers to the parent of the current class.

  • static - This refers to the called class. Thanks to inheritance, child classes can override methods and static properties. So calling them using static instead of a class name allows us to resolve where the call came from, rather than the current level.

Examples

The easiest way to understand this is to start looking at some examples. Let's pick a class:

class Person {
    public static $number = 0;
    public $id = 0;
    public function __construct() {
        self::$number++;
        $this->id = self::$number;
    }
    public $name = "";
    public function getName() {
        return $this->name;
    }
    public function getId() {
        return $this->id;
    }
}

class Child extends Person {
    public $age = 0;
    public function __construct($age) {
        $this->age = $age;
        parent::__construct();
    }
    public function getName() {
        return 'child: ' . parent::getName();
    }
}

Now, we're also looking at inheritance here. Ignore for a moment that this is a bad object model, but let's look at what happens when we play with this:

$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3

So the ID counter is shared across both instances and the children (because we're using self to access it. If we used static, we could override it in a child class).

var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy

Note that we're executing the Person::getName() instance method every time. But we're using the parent::getName() to do it in one of the cases (the child case). This is what makes this approach powerful.

Word Of Caution #1

Note that the calling context is what determines if an instance is used. Therefore:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

Is not always true.

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

Now it is really weird here. We're calling a different class, but the $this that gets passed to the Foo::isFoo() method is the instance of $bar.

This can cause all sorts of bugs and conceptual WTF-ery. So I'd highly suggest avoiding the :: operator from within instance methods on anything except those three virtual "short-cut" keywords (static, self, and parent).

Word Of Caution #2

Note that static methods and properties are shared by everyone. That makes them basically global variables. With all the same problems that come with globals. So I would be really hesitant to store information in static methods/properties unless you're comfortable with it being truly global.

Word Of Caution #3

In general you'll want to use what's known as Late-Static-Binding by using static instead of self. But note that they are not the same thing, so saying "always use static instead of self is really short-sighted. Instead, stop and think about the call you want to make and think if you want child classes to be able to override that static resolved call.

TL/DR

Too bad, go back and read it. It may be too long, but it's that long because this is a complex topic

TL/DR #2

Ok, fine. In short, self is used to reference the current class name within a class, where as $this refers to the current object instance. Note that self is a copy/paste short-cut. You can safely replace it with your class name, and it'll work fine. But $this is a dynamic variable that can't be determined ahead of time (and may not even be your class).

TL/DR #3

If the object-operator is used (->), then you always know you're dealing with an instance. If the scope-resolution-operator is used (::), you need more information about the context (are we in an object-context already? Are we outside of an object? etc).

Pumpkin answered 10/6, 2013 at 15:21 Comment(7)
Word of Caution #1: $this will not be defined when calling a static method: 3v4l.org/9kr0eSeizure
Well... $this will not be defined if you follow "Strict Standards" and don't call methods statically that aren't defined as static. I see the result you explained here: 3v4l.org/WeHVM Agreed, really weird.Seizure
@machee: Only if it's declared static. Which was the point I was trying to make: that it's tricky to know and see what's happening without digging through the code...Pumpkin
After reading the long description completely, I felt lazy to scroll above again to upvote it. Just joking, I did upvote it :D. Thanks this is very useful.Fougere
would be nice to add a clear explanation about the difference between self::$property and self::property; I think thats quite confusing tooElimination
WoC#1 behaves differently since PHP 7. As Foo::isFoo() is called statically, $this will not be defined. That's more intuitive behavior in my opinion. -- Another different result is given if Bar were to extend from Foo. Then the call Foo::isFoo() would be actually be within the instance context (not specific to PHP7).Ramon
This answer is great, very clear and very useful. I'd like to ask for a clarification. When you mention the 3 short-cut keywords, self, parent and static I went looking for an example below where you would make a call using static::foo()... but that doesn't exist, does it? Maybe the text could explain the difference better than that "This refers to the called class". Thanks.Bridgeport
M
123

self (not $self) refers to the type of class, whereas $this refers to the current instance of the class. self is for use in static member functions to allow you to access static member variables. $this is used in non-static member functions, and is a reference to the instance of the class on which the member function was called.

Because this is an object, you use it like: $this->member

Because self is not an object, it's basically a type that automatically refers to the current class. You use it like: self::member

Marie answered 30/9, 2008 at 7:26 Comment(2)
what does the type mean in type of class?Horatia
@Horatia "Type" here refers to the data type that describes the class. When you write class Test { ... } you are creating a new data type, alongside the built-in ones like int, string, DateTime, etc. When you write $x = new Test, $x becomes an object of type Test.Marie
E
102

$this-> is used to refer to a specific instance of a class's variables (member variables) or methods.

Example: 
$derek = new Person();

$derek is now a specific instance of Person. Every Person has a first_name and a last_name, but $derek has a specific first_name and last_name (Derek Martin). Inside the $derek instance, we can refer to those as $this->first_name and $this->last_name

ClassName:: is used to refer to that type of class, and its static variables, static methods. If it helps, you can mentally replace the word "static" with "shared". Because they are shared, they cannot refer to $this, which refers to a specific instance (not shared). Static Variables (i.e. static $db_connection) can be shared among all instances of a type of object. For example, all database objects share a single connection (static $connection).

Static Variables Example: Pretend we have a database class with a single member variable: static $num_connections; Now, put this in the constructor:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

Just as objects have constructors, they also have destructors, which are executed when the object dies or is unset:

function __destruct()
{
    $num_connections--;
}

Every time we create a new instance, it will increase our connection counter by one. Every time we destroy or stop using an instance, it will decrease the connection counter by one. In this way, we can monitor the number of instances of the database object we have in use with:

echo DB::num_connections;

Because $num_connections is static (shared), it will reflect the total number of active database objects. You may have seen this technique used to share database connections among all instances of a database class. This is done because creating the database connection takes a long time, so it's best to create just one, and share it (this is called a Singleton Pattern).

Static Methods (i.e. public static View::format_phone_number($digits)) can be used WITHOUT first instantiating one of those objects (i.e. They do not internally refer to $this).

Static Method Example:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

As you can see, public static function prettyName knows nothing about the object. It's just working with the parameters you pass in, like a normal function that's not part of an object. Why bother, then, if we could just have it not as part of the object?

  1. First, attaching functions to objects helps you keep things organized, so you know where to find them.
  2. Second, it prevents naming conflicts. In a big project, you're likely to have two developers create getName() functions. If one creates a ClassName1::getName(), and the other creates ClassName2::getName(), it's no problem at all. No conflict. Yay static methods!

SELF:: If you are coding outside the object that has the static method you want to refer to, you must call it using the object's name View::format_phone_number($phone_number); If you are coding inside the object that has the static method you want to refer to, you can either use the object's name View::format_phone_number($pn), OR you can use the self::format_phone_number($pn) shortcut

The same goes for static variables: Example: View::templates_path versus self::templates_path

Inside the DB class, if we were referring to a static method of some other object, we would use the object's name: Example: Session::getUsersOnline();

But if the DB class wanted to refer to its own static variable, it would just say self: Example: self::connection;

Ellamaeellan answered 22/10, 2008 at 17:52 Comment(1)
Great answer. I just want to point out, when referring to a static attribute, you need to use a $ sign. For example self::$templates_pathKlink
M
31

From this blog post:

  • self refers to the current class
  • self can be used to call static functions and reference static member variables
  • self can be used inside static functions
  • self can also turn off polymorphic behavior by bypassing the vtable
  • $this refers to the current object
  • $this can be used to call static functions
  • $this should not be used to call static member variables. Use self instead.
  • $this can not be used inside static functions
Martyr answered 10/5, 2013 at 12:0 Comment(0)
M
27

In PHP, you use the self keyword to access static properties and methods.

The problem is that you can replace $this->method() with self::method()anywhere, regardless if method() is declared static or not. So which one should you use?

Consider this code:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

In this example, self::who() will always output ‘parent’, while $this->who() will depend on what class the object has.

Now we can see that self refers to the class in which it is called, while $this refers to the class of the current object.

So, you should use self only when $this is not available, or when you don’t want to allow descendant classes to overwrite the current method.

Mossy answered 29/12, 2014 at 13:20 Comment(0)
F
24

self refers to the current class (in which it is called),

$this refers to the current object. You can use static instead of self.

See the example:

class ParentClass {
    function test() {
        self::which();    // Outputs 'parent'
        $this->which();   // Outputs 'child'
    }

    function which() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function which() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

Output:

 parent
 child
Ferromanganese answered 1/1, 2016 at 6:36 Comment(0)
I
22

Inside a class definition, $this refers to the current object, while self refers to the current class.

It is necessary to refer to a class element using self, and refer to an object element using $this.

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  
Intricacy answered 8/5, 2013 at 6:58 Comment(0)
C
21

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();
?> 
Catalyze answered 6/12, 2011 at 11:26 Comment(0)
S
20

According to Static Keyword, there isn't any $self. There is only $this, for referring to the current instance of the class (the object), and self, which can be used to refer to static members of a class. The difference between an object instance and a class comes into play here.

Steenbok answered 30/9, 2008 at 6:29 Comment(1)
Suggestion: Read this answer when tripping on acid.Zischke
T
20
  • The object pointer $this to refers to the current object.
  • The class value static refers to the current object.
  • The class value self refers to the exact class it was defined in.
  • The class value parent refers to the parent of the exact class it was defined in.

See the following example which shows overloading.

<?php

class A {

    public static function newStaticClass()
    {
        return new static;
    }

    public static function newSelfClass()
    {
        return new self;
    }

    public function newThisClass()
    {
        return new $this;
    }
}

class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}


$b = new B;

var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A


class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}


$c = new C;

var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

Most of the time you want to refer to the current class which is why you use static or $this. However, there are times when you need self because you want the original class regardless of what extends it. (Very, Very seldom)

Thurmond answered 22/3, 2013 at 15:24 Comment(0)
U
17

I believe the question was not whether you can call the static member of the class by calling ClassName::staticMember. The question was what's the difference between using self::classmember and $this->classmember.

For example, both of the following examples work without any errors, whether you use self:: or $this->

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}
Usurious answered 18/5, 2009 at 19:42 Comment(3)
It's especially funny that you start your answer with "I believe question was not whether you can call the static member of the class by calling ClassName::staticMember. Question was what's the difference between using self::classmember and $this->classmember" and then you proceed to show no differences at all. In fact, you show an instance of where the two options work identically. -1Artur
Nevertheless usefull. The scope was about resolution and this part is not clear in the php manual. I still find it usefullCosgrave
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16Salver
C
14

Here is a small benchmark (7.2.24 on repl.it):

            Speed (in seconds)  Percentage
$this->     0.91760206222534    100
self::      1.0047659873962     109.49909865716
static::    0.98066782951355    106.87288857386

Results for 4 000 000 runs. Conclusion: it doesn't matter. And here is the code I used:

<?php

class Foo
{
  public function calling_this() { $this->called(); }
  public function calling_self() { self::called(); }
  public function calling_static() { static::called(); }
  public static function called() {}
}

$foo = new Foo();
$n = 4000000;
$times = [];

// warmup
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }

$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
$times["this"] = microtime(true)-$start;

$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
$times["self"] = microtime(true)-$start;

$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }
$times["static"] = microtime(true)-$start;

$min = min($times);
echo $times["this"] . "\t" . ($times["this"] / $min)*100 . "\n";
echo $times["self"] . "\t" . ($times["self"] / $min)*100 . "\n";
echo $times["static"] . "\t" . ($times["static"] / $min)*100 . "\n";
Colston answered 31/5, 2015 at 7:9 Comment(5)
Calling no-op function 2 000 000 times lasts 1s. Gotta love PHP.Nonperformance
Good old PHP. :) But a call = 0.001ms. Is it that bad?Colston
I believe this (and similar things) is why things such as ORMs feel slow unless you cache stuff, and static site generators are a thing.Nonperformance
It should theoretically take 1 processor clock cycle, which makes around 1 / 2e9 s = 0.5 ns these daysOsteomyelitis
Just re-read my answer. Be careful: it creates the class too. I don't know why I didn't use the use keyword tbh, but I don't have PHP anymore to redo a benchmark, and I don't really feel like reinstalling it.Colston
M
13

When self is used with the :: operator it refers to the current class, which can be done both in static and non-static contexts. $this refers to the object itself. In addition, it is perfectly legal to use $this to call static methods (but not to refer to fields).

Murraymurre answered 22/3, 2013 at 15:13 Comment(0)
T
12

I ran into the same question and the simple answer was:

  • $this requires an instance of the class
  • self:: doesn't

Whenever you are using static methods or static attributes and want to call them without having an object of the class instantiated, you need to use self: to call them, because $this always requires an object to be created.

Teheran answered 19/5, 2018 at 15:23 Comment(0)
M
7

$this refers to the current class object, and self refers to the current class (Not object). The class is the blueprint of the object. So you define a class, but you construct objects.

So in other words, use self for static and this for none-static members or methods.

Also in a child/parent scenario, self / parent is mostly used to identify child and parent class members and methods.

Maestoso answered 15/9, 2014 at 6:36 Comment(0)
K
7

Additionally since $this:: has not been discussed yet.

For informational purposes only, as of PHP 5.3 when dealing with instantiated objects to get the current scope value, as opposed to using static::, one can alternatively use $this:: like so.

http://ideone.com/7etRHy

class Foo
{
    const NAME = 'Foo';

    //Always Foo::NAME (Foo) due to self
    protected static $staticName = self::NAME;

    public function __construct()
    {
        echo $this::NAME;
    }

    public function getStaticName()
    {
       echo $this::$staticName;
    }
}

class Bar extends Foo
{
    const NAME = 'FooBar';

    /**
     * override getStaticName to output Bar::NAME
     */
    public function getStaticName()
    {
        $this::$staticName = $this::NAME;
        parent::getStaticName();
    }
}

$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar

Using the code above is not common or recommended practice, but is simply to illustrate its usage, and is to act as more of a "Did you know?" in reference to the original poster's question.

It also represents the usage of $object::CONSTANT for example echo $foo::NAME; as opposed to $this::NAME;

Kathrinekathryn answered 29/9, 2014 at 19:28 Comment(0)
F
6

Use self if you want to call a method of a class without creating an object/instance of that class, thus saving RAM (sometimes use self for that purpose). In other words, it is actually calling a method statically. Use this for object perspective.

Fresco answered 10/4, 2013 at 15:13 Comment(0)
G
6

self:: A keyword used for the current class and basically it is used to access static members, methods, and constants. But in case of $this, you cannot call the static member, method, and functions.

You can use the self:: keyword in another class and access the static members, method, and constants. When it will be extended from the parent class and the same in case of the $this keyword. You can access the non-static members, method and function in another class when it will be extended from the parent class.

The code given below is an example of the self:: and $this keywords. Just copy and paste the code in your code file and see the output.

class cars{
    var $doors = 4;
    static $car_wheel = 4;

    public function car_features(){
        echo $this->doors . " Doors <br>";
        echo self::$car_wheel . " Wheels <br>";
    }
}

class spec extends cars{
    function car_spec(){
        print(self::$car_wheel . " Doors <br>");
        print($this->doors . " Wheels <br>");
    }
}

/********Parent class output*********/

$car = new cars;
print_r($car->car_features());

echo "------------------------<br>";

/********Extend class from another class output**********/


$car_spec_show = new spec;

print($car_spec_show->car_spec());
Gynandromorph answered 16/4, 2020 at 19:19 Comment(0)
S
2

Case 1: Use self can be used for class constants

 class classA { 
     const FIXED_NUMBER = 4; 
     self::POUNDS_TO_KILOGRAMS
}

If you want to call it outside of the class, use classA::POUNDS_TO_KILOGRAMS to access the constants

Case 2: For static properties

class classC {
     public function __construct() { 
     self::$_counter++; $this->num = self::$_counter;
   }
}
Shrug answered 2/2, 2016 at 20:51 Comment(0)
C
1

According to php.net there are three special keywords in this context: self, parent and static. They are used to access properties or methods from inside the class definition.

$this, on the other hand, is used to call an instance and methods of any class as long as that class is accessible.

Cordey answered 7/12, 2015 at 10:21 Comment(0)
O
1

Though this is an old question, as a newbie, I find the following comparison useful. Esp. the rules and syntax needed to use with self and $this.


// A. Definitions
   
// Three classes bar1 for parallel use, and bar2 and bar3 for linear use;

class bar1 {
    // Class bar1 to use the object method "$this",
    // to create multiple parallel instances;
    
    public $foo = 111; // Property "$foo" set without "static" keyword; 
    // because we will be using the object method "$this",
    // to create multiple (unique and fresh) instances;
    
    public function getfoo() {
        return $this->foo; // Function "getfoo" returns the value of property "foo";
        // While calling the property using "$this", no "$" symbol is used; 
        // By calling our class "bar1" using "$this" instead of "self", 
        // we can use on multiple instances;
    }
    public function setfoo($foo) {
        $this->foo = $foo; // Function "setfoo" sets the value of property "foo"; 
        // While calling the property using "$this", no "$" symbol is used; 
        // By calling our class "bar1" using "$this" instead of "self", 
        // we can use on multiple instances;
    }
}

class bar2 {
    // Class bar2 to use the static method "self" to use as single linear instance;
    // Note the use of "::" (scope resolution operator) instead of object call "->" 
    
    public static $foo = 111; // Property "$foo" set with "static" keyword; 
        // because we will be using the static method "self" to use as single instance;
    
    public static function getfoo() {
        return self::$foo; // Function "getfoo" returns the value of property "foo"; 
        // While calling the property using "self", "$" symbol is necessary; 
        // We are calling our class "bar2" using "self" instead of "$this", 
        // because we are using static method "self" to use as single instance;
    }
    public static function setfoo($foo) {
        self::$foo = $foo; // Function "setfoo" sets the value of property "foo"; 
        // While calling the property using "self", "$" symbol is necessary; 
        // We are calling our class "bar2" using "self" instead of $this, 
        // because we are using static method "self" to use as single instance;
    }
}

class bar3 {
    // Class bar3 is same as bar2 and uses the static method "self", 
    // except it sets the property "$foo" using "__construct" constructor method;
    // so it can be used as a single linear instance,
    // which can be optionally reset/reinitialized;
    
    public static $foo; // Property "$foo" initialized with "static" keyword;
        // No value is set here because we are setting it using "__construct" instead;
        
    public function __construct() { // "__construct" will set the property values
        self::$foo = 111;
    }
    
    public static function getfoo() {
        return self::$foo;
    }
    public static function setfoo($foo) {
        self::$foo = $foo;
    }
}

// B. Tests


// B.1 Object method; Parallel instances $x and $y;

$x = new bar1(); // Fresh instance $x
echo $x->getfoo().PHP_EOL; // Output: 111 
$x->setfoo(123); // Updated instance $x
echo $x->getfoo().PHP_EOL.PHP_EOL; // Output: 123

$y = new bar1(); // Fresh instance $y
echo $y->getfoo().PHP_EOL; // Output: 111 
$y->setfoo(143); // Updated instance $y
echo $y->getfoo().PHP_EOL.PHP_EOL; // Output: 143


// B.2 Static method; Single linear instance;

new bar2(); // Not a fresh instance; Can be omitted;
echo bar2::getfoo().PHP_EOL; // Output: 111 
bar2::setfoo(123); // Updated the same static instance
echo bar2::getfoo().PHP_EOL.PHP_EOL; // Output: 123 

new bar2(); // Not a fresh instance; Can be omitted;
echo bar2::getfoo().PHP_EOL; // Output: 123
bar2::setfoo(143); // Updated the same static instance
echo bar2::getfoo().PHP_EOL.PHP_EOL; // Output: 143


// B.3 Static method using __construct; Single linear yet re-settable instance;

new bar3(); // Resets into a fresh instance; Omitting this line will reuse old instance;
echo bar3::getfoo().PHP_EOL; // Output: 111 
bar3::setfoo(123); // Updated the same static instance
echo bar3::getfoo().PHP_EOL.PHP_EOL; // Output: 123 

new bar3(); // Resets into a fresh instance; Omitting this line will reuse old instance;
echo bar3::getfoo().PHP_EOL; // Output: 111
bar3::setfoo(143); // Updated the same static instance
echo bar3::getfoo().PHP_EOL.PHP_EOL; // Output: 143

Obscurantism answered 10/6, 2023 at 18:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.