self, static, and parent in PHP — What's the Real Difference and When to Use Each

self, static, and parent in PHP — What's the Real Difference and When to Use Each
Photo by Outsite Co / Unsplash

In PHP, object-oriented programming gives us several powerful keywords—self, static, and parent—to refer to classes within the class hierarchy. While they may seem similar, each has very specific behaviors, especially when dealing with inheritance, method resolution, and instantiation.

Understanding these keywords deeply is crucial for writing clean, predictable, and extensible code.


🔹 self: The Declaring Class

self refers to the class where the code is written, not where it is called from. This is a compile-time reference.

class A {
    public static function who() {
        echo "A\n";
    }

    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

B::test(); // Output: A

Even though B extends A, calling B::test() still prints A because self::who() is bound to class A. This is not polymorphic.


🔹 static: Late Static Binding

static uses late static binding, meaning it resolves to the class that was actually called at runtime, even if it’s a subclass. This is runtime-bound.

class A {
    public static function who() {
        echo "A\n";
    }

    public static function test() {
        static::who();
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

B::test(); // Output: B

Here, static::who() correctly resolves to class B. This is polymorphic and what you want when you expect child classes to override behavior.

Use static when:

  • You expect inheritance
  • You want the behavior to be overridden correctly
  • You are working with factories, fluent APIs, or interfaces with static return types

🔹 parent: Accessing the Superclass

parent is used to call methods from the immediate parent class. It’s strictly for accessing the parent’s implementation, often inside an override.

class A {
    public function greet() {
        echo "Hello from A\n";
    }
}

class B extends A {
    public function greet() {
        parent::greet();
        echo "And hello from B\n";
    }
}

$b = new B();
$b->greet();

Output:

Hello from A
And hello from B

Use parent when:

  • You override a method but still want to call the parent’s version
  • You're working in an inheritance chain and want to build on base behavior

🔍 Comparison Summary

Keyword Bound At Refers To Use Case
self Compile-time Class where code is written Internal helper methods, fixed behavior
static Runtime Class that was called Factory methods, polymorphic behavior
parent Compile-time Immediate parent class Overridden methods needing base behavior

✅ Real-World Considerations

  • self can break polymorphism. Be cautious when writing base class methods that use self, as they won't behave well when extended.
  • static is powerful but introduces complexity. Use it for factories or fluent interfaces when subclassing is expected.
  • parent is safe but very specific. Don't use it unless you're overriding methods and still need parent logic.

💡 Bonus Tip

When using static methods that return new instances (new static()), avoid new self() unless you're sure that the method won’t be extended or overridden. Even in a final class, using static is often more future-proof.


Understanding these keywords isn't just about syntax—it’s about design. Use the right keyword for the right behavior, and your codebase will be easier to maintain, less error-prone, and ready for change.

Support Us