Static members and constants
The properties you have declared so far belong to objects: each house has its own furniture. But sometimes you need a value shared by all the houses at once, such as how many houses have been built.
Such notes are kept right on the blueprint. The architect marks every new house on it, and there is one such mark for all the houses. And a line like "walls: brick" on the blueprint never changes.
A static property
Let's count how many users have been created:
<?php
class User
{
public static int $count = 0;
public function __construct(public string $name)
{
self::$count++;
}
}
$anna = new User('Anna');
$boris = new User('Boris');
echo User::$count, "\n"; // 2Let's go through it step by step:
public static int $count = 0;—the wordstaticmakes the property shared by the class: there is one slot, however many objects there are.- Inside the class it is reached through
self::$count.selfmeans "this class", and the$in the property name stays. - Each
new—new User('Anna')andnew User('Boris')—runs the constructor, and the constructor adds one to the shared counter. - From outside, the property is read through the class name, and
User::$countprints2.
A static property is a property that belongs to the class rather than to an object: there is one for all objects. The constructor runs on every new, even when the object is not stored anywhere: the line new User('Olga'); adds one too.
A constant and a static method
A line on the blueprint that never changes is a class constant. And a question you can ask the blueprint itself, without entering any house, is a static method:
<?php
class Password
{
const MIN_LENGTH = 8;
public static function isStrong(string $s): bool
{
return strlen($s) >= self::MIN_LENGTH;
}
}
var_dump(Password::isStrong('qwerty')); // bool(false)
echo Password::MIN_LENGTH, "\n"; // 8
echo Password::class, "\n"; // PasswordA class constant is a value set when the class is declared that cannot be changed. A static method is a method called on the class, with no object. Let's take it apart:
const MIN_LENGTH = 8;declares a constant. It has no$, and its name is written in capital letters.Password::isStrong('qwerty')calls the static method without any object.- Inside the class the constant is read through
self::MIN_LENGTH, outside throughPassword::MIN_LENGTH. Password::classgives the class name as a string,'Password'.
What else to know:
- a constant can hold a string or an array as well as a number:
const ROLE = 'member';; - a constant cannot be given a new value: the line
Password::MIN_LENGTH = 6;does not even parse, and the file never runs; - a constant is read only through
::, while$this->MIN_LENGTHlooks for a property by that name and gives aWarning; - an ordinary method cannot be called through
::: PHP 8 answers such a call with the errorNon-static method … cannot be called statically; - instead of
self::you sometimes seestatic::, and the difference between them shows up only when one class is built on top of another.
Here the blueprint picture is off. Only the architect edits the lines on a real blueprint, while a static property can be changed by any line of the program that can reach it. That is why changeable static properties are rare: a shared value is hard to keep track of.
Interviewers ask: "How is a static method different from an ordinary one?" The answer:
- a static method belongs to the class and is called as
Password::isStrong(), with no object, so it has no$this; - an ordinary method is called on an object, and
$thisin it is that object.
The second common question is when to use a constant and when a static property. A constant is for a value that never changes, and a static property is a changeable value shared by the whole class.
Common mistake
A static method uses $this:
<?php
class Greeter
{
public string $name = 'Anna';
public static function hello(): string
{
return 'Hi, ' . $this->name; // ✗
}
}
echo Greeter::hello(), "\n";Fatal error: Uncaught Error: Using $this when not in object contextThe static method was called on the class, there is no object, so there is no $this either. The fix is to remove the word static and call the method on an object: $greeter = new Greeter();, then echo $greeter->hello();.
Key points
- A static property is one for the whole class: inside it is read through
self::$count, outside throughUser::$count. - A class constant is set once, read through
self::NAMEorUser::NAME, and cannot be reassigned. - A static method is called on the class, with no object, and has no
$this. User::classgives the class name as a string.