Static members belong to the class rather than any specific instance. They are accessed with the :: scope resolution operator and the self:: / static:: keywords inside the class.
Static properties hold state shared across all instances.
Static methods are useful for factory methods, utility functions, and counters.
Use static:: instead of self:: when you want late static binding (important for inheritance).
Example
<?php
class Counter
{
private static int $count = 0;
public function __construct()
{
self::$count++;
}
public static function getCount(): int
{
return self::$count;
}
public static function reset(): void
{
self::$count = 0;
}
}
$a = new Counter();
$b = new Counter();
$c = new Counter();
echo Counter::getCount(); // 3 — shared across all instances
Counter::reset();
echo Counter::getCount(); // 0
// Factory / singleton pattern using static methods
class Config
{
private static ?Config $instance = null;
private array $data = [];
private function __construct() {} // prevent direct instantiation
public static function getInstance(): static
{
if (static::$instance === null) {
static::$instance = new static();
}
return static::$instance;
}
public function set(string $key, mixed $value): void
{
$this->data[$key] = $value;
}
public function get(string $key, mixed $default = null): mixed
{
return $this->data[$key] ?? $default;
}
}
$config = Config::getInstance();
$config->set('debug', true);
$same = Config::getInstance(); // returns the same instance
echo $same->get('debug') ? 'true' : 'false'; // true
Pro Tip
Tip: Avoid overusing static properties as global state — it makes code harder to test because static state persists between test cases. Prefer dependency injection; use statics sparingly for true class-level concerns like counters or caches.