Skip to content
Theory · Classes and objects · lesson 8 of 11

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
<?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"; // 2

Let's go through it step by step:

  1. public static int $count = 0;—the word static makes the property shared by the class: there is one slot, however many objects there are.
  2. Inside the class it is reached through self::$count. self means "this class", and the $ in the property name stays.
  3. Each new—new User('Anna') and new User('Boris')—runs the constructor, and the constructor adds one to the shared counter.
  4. From outside, the property is read through the class name, and User::$count prints 2.

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
<?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"; // Password

A 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:

  1. const MIN_LENGTH = 8; declares a constant. It has no $, and its name is written in capital letters.
  2. Password::isStrong('qwerty') calls the static method without any object.
  3. Inside the class the constant is read through self::MIN_LENGTH, outside through Password::MIN_LENGTH.
  4. Password::class gives 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_LENGTH looks for a property by that name and gives a Warning;
  • an ordinary method cannot be called through ::: PHP 8 answers such a call with the error Non-static method … cannot be called statically;
  • instead of self:: you sometimes see static::, 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 $this in 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
<?php

class Greeter
{
    public string $name = 'Anna';

    public static function hello(): string
    {
        return 'Hi, ' . $this->name; // ✗
    }
}

echo Greeter::hello(), "\n";
TEXT
Fatal error: Uncaught Error: Using $this when not in object context

The 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 through User::$count.
  • A class constant is set once, read through self::NAME or User::NAME, and cannot be reassigned.
  • A static method is called on the class, with no object, and has no $this.
  • User::class gives the class name as a string.