Home > Questions > PHP: self vs. $this

PHP: self vs. $this

1
127

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

When is each appropriate?

NOTE: This question was originally posted at StackOverflow.com by Casey Watson

  • Brenda
    "Such dumb questions" get high ratings because that many people find them when Googling for the same question. SO works because there are people with knowledge and people that need that knowledge.

    NOTE: This comment was originally posted at StackOverflow.com by Craig Hooghiem

  • Wendy
    hakre, Not a dumb question to me, it has a lot of informative answers with a lot more details than you would expect. @gameerfuse You must be the guy who down-votes all my legit questions.

    NOTE: This comment was originally posted at StackOverflow.com by Shane

  • You must to post comments
47
0

$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;

Hope that helps clear things up 🙂

NOTE: This answer was originally posted at StackOverflow.com by lo_fye

  • You must to post comments
1
0

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 what we see is “Person is alive” as the scope contains the original method definition when 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 its 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.

http://php.net/manual/en/language.oop5.late-static-bindings.php

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

NOTE: This answer was originally posted at StackOverflow.com by Sqoo

  • You must to post comments
1
0

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();
?> 

NOTE: This answer was originally posted at StackOverflow.com by Mohit Bumb

  • You must to post comments
1
0

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

NOTE: This answer was originally posted at StackOverflow.com by nbeagle

  • You must to post comments
Showing 4 results
Your Answer
Guest Author
Post as a guest by filling out the fields below or if you already have an account.
Name*
E-mail*
Website
CAPTCHA*
Enter the characters shown on the image.