PHP OOP: Understanding Static Methods
Learn PHP static methods: define and call them, self:: vs static:: (late static binding), static counters, factory methods, and gotchas — with examples.
A static method is a method declared with the static keyword that belongs to the class itself rather than to any single object created from it. Because it is tied to the class, you can call it directly with the class name and the scope-resolution operator (::) — no new required.
This chapter shows how to define and call static methods, how they differ from regular (instance) methods, how self:: and static:: behave inside them, and the patterns where static methods genuinely help (utilities, counters, and factory methods). If you are new to classes, read PHP Classes and Objects first.
What are static methods in PHP?
Regular methods operate on a specific object and can read its instance data through $this. A static method has no $this — it is not bound to any instance, so it can only work with the arguments you pass in and with the class's own static members.
That makes static methods a natural fit for stateless operations: a calculation that depends only on its inputs, not on the state of a particular object. Computing the average of a list of numbers is a classic example.
class Math
{
public static function average(array $numbers): float
{
return array_sum($numbers) / count($numbers);
}
}Why use static methods?
| Reason | What it means in practice |
|---|---|
| Statelessness | The output depends only on the arguments, so the result is predictable and easy to test. |
| No instantiation | You skip new ClassName() — handy for helper/utility functions. |
| Shared state | Static methods can read and update static properties, letting a class track data across all of its objects (e.g. a counter). |
| Factory methods | A static method can build and return a configured instance, giving you a clearer alternative to a complex constructor. |
The trade-off: because static methods can't be overridden through a normal object reference and don't carry instance state, overusing them makes code harder to mock and unit-test. Prefer instance methods when behavior depends on object state.
How to define and call a static method
Add static before the method name, then call it with ClassName::method():
<?php
class Math
{
public static function average(array $numbers): float
{
return array_sum($numbers) / count($numbers);
}
}
$average = Math::average([1, 2, 3, 4, 5]);
echo $average; // 3The :: token is the scope-resolution operator — the same operator you use for class constants.
self:: vs static:: and the missing $this
Inside a static method you cannot use $this, because there is no instance to refer to. To reach another static member of the class you use self:: or static::.
self::resolves to the class where the method is written.static::uses late static binding — it resolves to the class that was actually called at runtime, which matters with inheritance.
<?php
class Base
{
public static function create(): string
{
return self::class; // always "Base"
}
public static function make(): string
{
return static::class; // the called class
}
}
class Child extends Base {}
echo Base::create(), "\n"; // Base
echo Child::create(), "\n"; // Base (self:: is fixed to where it's written)
echo Child::make(), "\n"; // Child (static:: follows the call)Reach for static:: when a parent class defines behavior that subclasses should be able to redirect to themselves — the foundation of the factory pattern below. Learn more in PHP Inheritance.
Static methods with static properties: a counter
Static methods are commonly paired with static properties to keep state that is shared across every object of a class.
<?php
class User
{
public static int $count = 0;
public function __construct(public string $name)
{
self::$count++;
}
public static function total(): int
{
return self::$count;
}
}
new User('Ada');
new User('Linus');
echo User::total(); // 2Note how total() reads self::$count without an object — the property lives on the class, not on any single User.
Factory methods
A static method that returns a new instance is called a factory method. It gives a named, readable way to construct objects:
<?php
class Temperature
{
private function __construct(private float $celsius) {}
public static function fromCelsius(float $c): static
{
return new static($c);
}
public static function fromFahrenheit(float $f): static
{
return new static(($f - 32) * 5 / 9);
}
public function celsius(): float
{
return $this->celsius;
}
}
$t = Temperature::fromFahrenheit(212);
echo $t->celsius(); // 100Using new static() (late static binding) means a subclass that calls fromCelsius() gets an instance of itself, not of Temperature.
Common gotchas
$thisis unavailable. Using it inside a static method raises a fatal error — there is no current object.- Static and instance methods can share a name only across classes, not in one class. Within a class each method name is unique.
- You can call a static method on an object (
$obj::method()or even$obj->method()), but it still runs without$this. Calling it with$obj->is allowed but misleading — preferClassName::method()for clarity. - Static state is global to the process. A static counter is shared by every instance and persists for the whole request, which can surprise you in long-running or test code.
Conclusion
Static methods belong to the class, run without an instance, and have no access to $this. They shine for stateless utilities, class-wide state through static properties, and factory methods that build configured objects. Use self:: when you mean the defining class and static:: when subclasses should be able to redirect the call to themselves. Reach for static methods when behavior is tied to the class rather than to a particular object — and prefer instance methods when it isn't.
Next, deepen your understanding with PHP Static Properties and PHP Class Constants.