DEV Community

Karleb
Karleb

Posted on

Self and Static in PHP and their differences

New Static

new static() has been around since PHP 5.2. It is used in PHP classes and it returns the current class object in which it is called regardless of whether it was implemented in the current object or any of its parents.

It was named Late Static Binding because its static:: will be resolved on the latest or current object in which it is called. It is also called static binding as it can be used for static method calls but it is not limited to static method calls only.


class Dog {
    public function instance() {
        return new static();
    }

    public function getName() {
        return static::name();
    }

    public function name() {
        return __CLASS__;
    }
}

class Pitbull extends Dog {
    public function name() {
        return __CLASS__;
    }
}
var_dump((new Dog)->instance()); //Dog class instance
var_dump((new Pitbull)->instance()); //Pitbull class instance
var_dump((new Dog)->getName()); //Dog
var_dump((new Pitbull)->getName()); //Pitbull
Enter fullscreen mode Exit fullscreen mode

In the above example, the Dog class defines an instance() method that returns new static() which is the current class instance, getName() which returns the current class name that is defined in the name() method.

Pitbull class extends Dog class and inherits all its methods but overrides the name() method to display its own class name rather than its parent's.

When the instance() and getName() method of both classes are called, they return their respective class instances and names.

New Self

Unlike new static(), new self() returns the instance and object properties on the class in which it was defined not regarding if another class extends this class.

A call to new self() would resolve to the parent class and self:: would return the parent's methods and properties.


class Bird {
    public function instance() {
        return new self();
    }

    public function getName() {
        return self::name();
    }

    public function name() {
        return __CLASS__;
    }
}

class Eagle extends Bird {
    public function name() {
        return __CLASS__;
    }
}
var_dump((new Bird)->instance()); //Bird class instance
var_dump((new Eagle)->instance()); //Bird class instance
var_dump((new Bird)->getName());  //Bird
var_dump((new Eagle)->getName()); //Bird
Enter fullscreen mode Exit fullscreen mode

The Bird class defines an instance() method that returns new self(), that is, the class instance itself. getName() returns the current class name which is expressed in the name() method.

Eagle class extends Bird class and inherits all its methods but overrides the name() method to display its class name rather than its parent's.

When the instance() and getName() method of both classes are called, they return the name and class instance of the Bird class.

Why Not Use $this?

You might ask why not just use $this which returns the current object instance?

By using $this to access the instance-level property and methods, each object can have its own unique value for properties and methods. This allows to store and manipulate state data for individual objects.

But self can access class-level properties and methods. With this, we can create properties that are shared among all instances of the class. This can be useful when we want to keep track of a global state that is not specific to any individual object.

Finally, by using static to access the class-level properties and methods, we create properties that are shared among all instances of the class but can be modified at runtime by individual objects. This allows for greater flexibility and modularity in the code, as we can change the behavior of the class at runtime by modifying the properties and methods of individual objects.


class Animal {
    private static $count = 0;
    private $name;

    public function __construct($name) {
        $this->name = $name;
        self::$count++; 
    }

    public function getName() {
        return $this->name;
    }

    public static function getCount() {
        return self::$count; 
    }

    public function incrementCount() {
        static::$count++; 
    }
}

$animal1 = new Animal("Cat");
$animal2 = new Animal("Dog");
$animal3 = new Animal("Bird");

echo $animal1->getName(); // Output: Cat
echo $animal2->getName(); // Output: Dog
echo $animal3->getName(); // Output: Bird

echo Animal::getCount(); // Output: 3

$animal1->incrementCount(); // Increment the class-level count property using static
echo Animal::getCount(); // Output: 4
Enter fullscreen mode Exit fullscreen mode

Conclusion

self and static have their respective uses in PHP.

self is resolved at compile time and will always refer to the class that defines it no matter the class that inherits this class. It is useful for keeping track of global class values.

static on the other hand is resolved at runtime and allows modification of properties at each class level.

Top comments (0)