Self and Static in PHP and their differences
Tags: php, webdev, programming
Published: 2023-03-17 02:59:49

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

```php

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

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.

```php

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

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.

```php

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

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