Understanding Static Properties in PHP OOP
Object Oriented Programming (OOP) is a programming paradigm that allows developers to create objects, which can be treated as instances of a class. The class
A static property belongs to the class itself rather than to any single object created from it. While a regular (instance) property gets its own copy in every object, a static property exists exactly once and is shared by every instance — change it in one place and all instances see the new value. This page explains how to declare static properties, how to read and write them, how self, static, and parent differ, how they behave with inheritance, and the gotchas to watch for.
If you are new to PHP classes, start with PHP Classes and Objects first.
What is a static property?
You declare a static property with the static keyword, combined with a visibility modifier (public, protected, or private):
<?php
class User {
public static int $count = 0;
public function __construct() {
self::$count++;
}
}
new User();
new User();
new User();
echo User::$count; // 3Three things make a static property different from an ordinary one:
- Accessed via the class, not an object. You write
User::$countwith the scope-resolution operator::, not$user->count. Trying to read a static property through the arrow operator ($user->count) does not work and emits a notice. - Shared, not copied. Every
new User()increments the same$count. There is only one copy in memory for the whole class. - Referenced as
self::$countinside the class. Inside a method, you reach the property throughself::,static::, orparent::— never$this.
Reading and writing a static property
From inside the class, use self::$property. From outside, use ClassName::$property. Because there is only one copy, a write from any context is visible everywhere:
<?php
class Counter {
public static int $value = 0;
public static function increment(): void {
self::$value++;
}
}
Counter::increment();
Counter::increment();
Counter::$value += 10; // also writable directly from outside
echo Counter::$value; // 12A static property can have a default value, but that default must be a constant expression (a literal, a constant, or a simple const arithmetic expression) — it cannot be the result of a function call or a new object.
self:: vs static:: (late static binding)
Inside a method you can reach a static property with either self:: or static::. They differ when inheritance is involved:
self::is resolved at compile time and always points to the class where the code is written.static::uses late static binding — it points to the class the method was called on at runtime.
<?php
class Base {
public static string $label = "Base";
public static function whoAmISelf(): string {
return self::$label; // bound to Base
}
public static function whoAmIStatic(): string {
return static::$label; // bound to the calling class
}
}
class Child extends Base {
public static string $label = "Child";
}
echo Child::whoAmISelf(); // Base
echo "\n";
echo Child::whoAmIStatic(); // ChildUse static:: when you want subclasses to override the value; use self:: when the value should stay tied to the declaring class. See PHP Static Methods for more on calling static members.
When should you use static properties?
Static properties shine whenever a piece of state must be shared across every instance of a class:
- Counting instances — the
User::$countexample above tracks how many objects exist. - Caching / registries — store a lookup table or a single shared resource (e.g. a database connection handle) so it is created once and reused.
- Configuration or flags — a default that applies to the whole class, such as a global
User::$defaultRole. - The Singleton pattern — a private static property holds the single instance returned by
getInstance().
If the value should never change after declaration, prefer a class constant (const) instead — it expresses intent better and cannot be reassigned.
Common gotchas
- Static properties are not constants. They are mutable; any code with access can reassign them. Use
constfor values that must not change. - Shared state is a double-edged sword. Because all instances share the value, a change in one object surfaces everywhere — convenient for counters, dangerous if you expected per-object data.
- No
$thisin a static context. Static methods have no$this, so a static property must be reached withself::,static::, orparent::. - Inheritance shares the parent's storage unless redeclared. A subclass that does not redeclare a static property shares the parent's single copy; redeclaring it (as
Childdoes above) gives the subclass its own.
Conclusion
Static properties let a class hold state that is shared by all of its instances, accessed through the class name with the :: operator and through self::/static:: inside the class. They are ideal for counters, caches, registries, and singletons. Reach for a class const when the value must stay fixed, and remember that static:: enables late static binding so subclasses can override the value. Next, explore PHP Static Methods and PHP Inheritance to see how these pieces fit together.