<?php OOP: Zero to Hero Chapter 09 of 20

Chapter 09 ยท Going Deeper

Static & Constants

Everything so far belonged to individual objects โ€” each cookie carried its own data. But some things logically belong to the cutter itself: a counter of how many cookies were made, a shared setting, a utility calculation. That's what static is for.

๐Ÿซ
Real-world analogy

Every student has their own student number (object property). But the school's noticeboard is shared โ€” there's exactly one, and everyone reads the same board. A static property is that noticeboard: it belongs to the class itself, not to any single object. Change it, and everyone sees the change.

Static properties โ€” one shared value

<?php
class Student {
    public static int $count = 0;        // the shared noticeboard

    public function __construct(public string $name) {
        self::$count++;                  // every new student updates the shared counter
    }
}

new Student("Chanda");
new Student("Mutinta");
new Student("Bwalya");

echo "Students registered: " . Student::$count;
Students registered: 3

Two brand-new symbols:

Careful with the dollar sign

With objects: $this->name (no $ after the arrow). With statics it's the opposite: self::$count โ€” the $ stays. Mixing these up is the number-one static syntax error.

Static methods โ€” skills that need no object

A static method belongs to the class and is called without creating any object. Perfect for utility work that doesn't depend on any particular object's data:

class Fees {
    public static function withVat(float $amount): float {
        return round($amount * 1.16, 2);
    }

    public static function format(float $amount): string {
        return "K" . number_format($amount, 2);
    }
}

// No "new" anywhere โ€” call directly on the class:
echo Fees::format(Fees::withVat(5000));
K5,800.00
The iron rule of static methods

Inside a static method there is no $this. Think about it: the method runs without any object existing โ€” so "me, myself" points at nobody. If a method needs $this, it cannot be static. If it never touches $this, it's a candidate for static.

Class constants โ€” values carved in stone

Constants are values that never change โ€” no $, written in CAPITALS by convention, accessed with :::

class Grade {
    const PASS_MARK   = 50;
    const DISTINCTION = 75;

    public static function of(int $marks): string {
        if ($marks >= self::DISTINCTION) return "Distinction";
        if ($marks >= self::PASS_MARK)   return "Pass";
        return "Fail";
    }
}

echo "Pass mark is " . Grade::PASS_MARK . "<br>";
echo "67 => " . Grade::of(67);
Pass mark is 50 67 => Pass

Why constants instead of plain numbers scattered in the code? Because Grade::PASS_MARK explains itself, lives in exactly one place, and if the university senate changes the pass mark to 45, you edit one line and the whole system follows. Numbers sprinkled through code ("magic numbers") are a maintenance nightmare.

A realistic combined example

class StudentNumber {
    const PREFIX = "LGU";
    private static int $lastSerial = 0;

    public static function generate(int $year): string {
        self::$lastSerial++;
        // str_pad turns 7 into "007"
        return self::PREFIX . $year . "-" . str_pad(self::$lastSerial, 3, "0", STR_PAD_LEFT);
    }
}

echo StudentNumber::generate(2026) . "<br>";
echo StudentNumber::generate(2026) . "<br>";
echo StudentNumber::generate(2026);
LGU2026-001 LGU2026-002 LGU2026-003

A shared constant, a shared private counter, a public static generator โ€” no objects needed. This is exactly how real systems mint sequential IDs, invoice numbers and receipt numbers.

When to use static โ€” and when not to

โœ๏ธ Try it yourself

Build a class Converter with a constant KWACHA_PER_DOLLAR = 27.5 and two static methods: toKwacha(float $usd) and toDollars(float $zmw). Convert $100 to Kwacha and K550 to dollars, printing both.

Show solution
<?php
class Converter {
    const KWACHA_PER_DOLLAR = 27.5;

    public static function toKwacha(float $usd): float {
        return round($usd * self::KWACHA_PER_DOLLAR, 2);
    }

    public static function toDollars(float $zmw): float {
        return round($zmw / self::KWACHA_PER_DOLLAR, 2);
    }
}

echo "$100 = K" . Converter::toKwacha(100) . "<br>";
echo "K550 = $" . Converter::toDollars(550);
$100 = K2750 K550 = $20
Quick quiz

How do you access a static property from outside the class?

Quick quiz

Why can't a static method use $this?

๐Ÿ”‘ Key points
  • static members belong to the class (one shared noticeboard), not to objects.
  • Access with :: โ€” from outside: Student::$count; from inside: self::$count.
  • Static methods are called without new and can never use $this.
  • const NAME = value; defines unchangeable class constants โ€” CAPITALS, no $.
  • Constants kill "magic numbers": one named value, one place to change it.
  • Use static for shared counters, utilities and config โ€” not as a lazy way to avoid objects.