June 5, 2025

What is self in PHP

In PHP, self is a special keyword used within a class to refer to the class itself, not an object instance. It’s typically used to access:

  • Static properties
  • Static methods
  • Constants
  • The current class scope (like in late static binding)

Example 1: Accessing a static property

class MyClass {
    public static $name = "ChatGPT";

    public static function getName() {
        return self::$name;  // Using self to access static property
    }
}

echo MyClass::getName(); // Output: ChatGPT

Example 2: Accessing a class constant

class Config {
    const SITE_NAME = "MySite";

    public function showSiteName() {
        return self::SITE_NAME;  // Using self to access constant
    }
}

❗ Difference from $this

KeywordRefers toUse case
$thisThe current objectAccess non-static properties/methods
selfThe class itselfAccess static properties/methods/constants

⚠️ Tip:

  • If you’re doing inheritance and want the method/property from the child class, use static:: (called late static binding) instead of self::.

Let’s walk through a comparison between self:: and static:: in PHP using a real inheritance example, so you can see why static:: (aka late static binding) is more flexible.


πŸ” Scenario:

You have a base class and a subclass. Each defines its own version of a static method or property.


βœ… self:: Example (Early binding – refers to the class where it’s defined)

class ParentClass {
    public static function who() {
        return "Parent";
    }

    public static function call() {
        return self::who(); // Always refers to ParentClass::who()
    }
}

class ChildClass extends ParentClass {
    public static function who() {
        return "Child";
    }
}

echo ChildClass::call(); // Output: Parent ❌ (not what we want)

πŸ’‘ Even though you called ChildClass::call(), it uses self::who(), which refers to ParentClass::who() – not dynamic.


βœ… static:: Example (Late Static Binding – resolves to the calling class)

class ParentClass {
    public static function who() {
        return "Parent";
    }

    public static function call() {
        return static::who(); // Will use the child class version if available
    }
}

class ChildClass extends ParentClass {
    public static function who() {
        return "Child";
    }
}

echo ChildClass::call(); // Output: Child βœ…

πŸŽ‰ static::who() defers resolution until runtime and correctly uses the overridden ChildClass::who() method.


🧠 Summary

KeywordBehaviorExample Use
self::Early binding to the current class (where it is written)Constants, base-only logic
static::Late static binding – resolves to the class that was called at runtimeExtensible methods, polymorphism

Early Static Binding (self::)

It always refers to the current class where the code is written, even if you call it from a child class.

πŸ”§ Example:

class Animal {
    public static function type() {
        echo "Animal";
    }

    public static function sayType() {
        self::type();  // This always calls Animal::type()
    }
}

class Dog extends Animal {
    public static function type() {
        echo "Dog";
    }
}

Dog::sayType();  // Output: Animal

βœ… When to use:

  • You want the same fixed behavior, no matter who calls it.
  • You are writing a helper or utility method that should not change.

βœ… Late Static Binding (static::)

It uses the class that actually calls it, so if a child class calls it, the child’s version will be used.

πŸ”§ Example:

class Animal {
    public static function type() {
        echo "Animal";
    }

    public static function sayType() {
        static::type();  // This will call the type() of the class that calls it
    }
}

class Dog extends Animal {
    public static function type() {
        echo "Dog";
    }
}

Dog::sayType();  // Output: Dog

βœ… When to use:

  • You want child classes to override the behavior.
  • You are building a base class, and you want the child class to customize it.
  • You’re using factory methods or static inheritance.

🧠 Real-Life Analogy

  • self:: is like saying β€œI will always use my version of the tool, even if someone else calls me.”
  • static:: is like saying β€œI will use your version of the tool, whoever calls me.”

πŸ“ Simple Summary

Featureself:: (Early)static:: (Late)
Fixed to the base classβœ… Yes❌ No
Can be overridden by child❌ Noβœ… Yes
Used for utility/helperβœ… Yes❌ No
Used in inheritance/factory❌ Noβœ… Yes