🐶
PHP

PHP New Self vs Static: Understanding the Difference

By Filip on 10/31/2024

This article compares and contrasts the 'new self' and 'new static' keywords in PHP, explaining their nuanced differences and when to use each for object-oriented programming.

PHP New Self vs Static: Understanding the Difference

Table of Contents

Introduction

In object-oriented programming, creating new objects within a class is a fundamental concept. PHP, a popular language for web development, provides two keywords for this purpose: new self and new static. While both seem similar at first glance, they exhibit distinct behaviors, especially when inheritance comes into play. Understanding these differences is crucial for writing flexible and maintainable code.

Step-by-Step Guide

new self and new static are both used to create new objects within a class, but they behave differently when inheritance is involved.

new self:

  • Always refers to the class where the code is written.
  • Useful for creating instances of the same class, even within subclasses.
class A {
  public function create() {
    return new self(); // Always creates an instance of class A
  }
}

new static:

  • Refers to the class where the method is called (late static binding).
  • Allows subclasses to create instances of themselves, not the parent class.
class A {
  public function create() {
    return new static(); // Creates an instance of the called class
  }
}

class B extends A {
}

$b = new B();
$b->create(); // Creates an instance of class B

In summary:

  • Use new self when you always want to create an instance of the current class, regardless of inheritance.
  • Use new static when you want the created instance to reflect the class where the method is called, allowing for polymorphism.

Code Example

The PHP code defines an Animal class with a generic sound and two methods for creating new instances: createNew() using "new static" and createNewSelf() using "new self". It then defines a Dog class that inherits from Animal and overrides the makeSound() method. The code demonstrates the difference between "new static" and "new self" when inheritance is involved. Using "new static" on a Dog object creates a new Dog object, while "new self" creates a new Animal object, highlighting how "new static" respects the called class and "new self" refers to the class where the method is defined.

<?php

class Animal
{
  protected string $name;

  public function __construct(string $name)
  {
    $this->name = $name;
  }

  public function makeSound(): string
  {
    return "Generic animal sound";
  }

  public function createNew(): static
  {
    return new static($this->name);
  }

  public function createNewSelf(): self
  {
    return new self($this->name);
  }
}

class Dog extends Animal
{
  public function makeSound(): string
  {
    return "Woof!";
  }
}

// Using new static
$dog = new Dog("Buddy");
$newDog = $dog->createNew(); // Creates a new Dog object

echo $newDog->makeSound(); // Output: Woof!

// Using new self
$anotherDog = $dog->createNewSelf(); // Creates a new Animal object

echo $anotherDog->makeSound(); // Output: Generic animal sound

?>

Explanation:

  1. Animal Class:

    • Defines basic animal properties and methods.
    • createNew() uses new static to create a new instance of the called class.
    • createNewSelf() uses new self to create a new instance of the Animal class.
  2. Dog Class:

    • Inherits from Animal.
    • Overrides makeSound() for a dog-specific sound.
  3. Usage:

    • We create a Dog object named $dog.
    • Calling $dog->createNew() utilizes new static, resulting in a new Dog object ($newDog).
    • Calling $newDog->makeSound() confirms it's a Dog by outputting "Woof!".
    • Calling $dog->createNewSelf() utilizes new self, resulting in a new Animal object ($anotherDog), even though called on a Dog object.
    • Calling $anotherDog->makeSound() confirms it's an Animal by outputting "Generic animal sound".

This example clearly demonstrates the difference between new self and new static in PHP when inheritance is involved. new static respects the actual class being used, while new self always refers to the class where the code is defined.

Additional Notes

Conceptual Understanding:

  • Think of self as "hardcoded" and static as "dynamic". self always points to the class where it's written, while static adapts to the class being used during runtime.
  • Late Static Binding is Key: The behavior of new static is directly tied to PHP's late static binding feature (introduced in PHP 5.3). This feature defers the resolution of static method calls and property accesses until runtime, enabling more flexible inheritance patterns.

Practical Implications:

  • Factory Methods: new static is particularly useful in factory methods, where you want a method to create instances of the class it's called from, even in subclasses.
  • Abstract Classes: When used within abstract classes, new static allows concrete subclasses to instantiate themselves, promoting the Open/Closed principle.
  • Potential for Confusion: While powerful, new static can make code harder to reason about at a glance, especially for developers unfamiliar with late static binding. Clear comments and documentation are essential.

Best Practices:

  • Favor new static for Flexibility: In most cases where you're creating new objects within a class, new static offers greater flexibility and aligns better with object-oriented principles.
  • Use new self Deliberately: Reserve new self for situations where you explicitly need to create an instance of the current class, regardless of inheritance. Document this reasoning clearly.
  • Prioritize Readability: If using new static significantly impacts code clarity, consider alternative approaches or provide comprehensive explanations to avoid confusion.

Beyond the Basics:

  • Interaction with Traits: The behavior of self and static can become more nuanced when traits are involved. It's important to understand how late static binding interacts with trait inheritance.
  • Performance Considerations: While the performance difference between new self and new static is usually negligible, it's worth considering in performance-critical applications.

By mastering the distinctions between new self and new static, PHP developers can write more robust, extensible, and maintainable object-oriented code.

Summary

Feature new self new static
Refers to... The class where the code is written. The class where the method is called.
Inheritance behavior Always creates an instance of the same class, even in subclasses. Creates an instance of the called class, allowing subclass instantiation.
Use case When you need to guarantee the creation of a specific class instance, regardless of inheritance. When you want polymorphic behavior, allowing subclasses to create their own instances.

In essence:

  • new self provides predictability.
  • new static provides flexibility.

Conclusion

Choosing between new self and new static in PHP depends on the desired behavior regarding inheritance. new self consistently creates instances of the class where it's defined, proving useful when a specific class instance is always required. Conversely, new static leverages late static binding to create instances of the class the method is called from, making it ideal for scenarios requiring polymorphic object creation. Understanding this distinction is crucial for PHP developers aiming to write flexible and maintainable object-oriented code, especially when inheritance is involved. By carefully considering the desired level of flexibility and predictability, developers can choose the most appropriate keyword for their specific use case, ultimately leading to more robust and well-structured applications.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait