Summary - Static members
Build a counter class with static property, method and self::.
Summary - Static members
In this group you learned static members. A static property is shared state on the class (Counter::$count); a static method is callable without an instance (MathHelper::square(4)).
Inside a class you reach static members with self::, safer than hardcoding the class name. self:: binds to the written class; static:: binds to the called class (late static binding).
Example: in a Counter class, self::$count++ in the constructor tracks instance count; static::class in an inherited method returns the subclass name.
Exercise Counter class: static property and self::
Define a Counter class with a public static int $count = 0 property. The constructor does self::$count++. public static function getCount(): int does return self::$count. public static function reset(): void does self::$count = 0. Call new Counter() three times, write echo Counter::getCount() . "\n", then call Counter::reset() and write echo Counter::getCount() . "\n" again.
Show example solution
:$count++. Add static function getCount(): int { return self::$count; } and static function reset(): void { self::$count = 0; }. Call new Counter() three times, echo Counter::getCount(), Counter::reset(), echo Counter::getCount().
Example solution:
<?php
// Summary: static counter class
class Counter {
public 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;
}
}
new Counter();
new Counter();
new Counter();
echo Counter::getCount() . "\n";
Counter::reset();
echo Counter::getCount() . "\n";
Best practices with static members
A few best practices with static members: keep static properties small and predictable; always reset them in tests. Large global state increases complexity.
When you need instance state, use instance, not static. Static methods do not support polymorphism, so subclasses cannot behave differently; in that case static:: with late binding can be a way out.
Common patterns: Singleton (single instance), Registry (name-value pool), Factory (new static() returns an instance of the called class). Use them carefully and where appropriate.
Exercise LSB example: Shape and Circle
Define a Shape class. The public static function create(): static method does return new static(). The public function name(): string method does return static::class. Then add an empty class Circle extends Shape {} subclass. Create an instance with $s = Circle::create() and write echo $s->name() . "\n". The expected output is Circle.
Show example solution
static { return new static(); } and function name(): string { return static::class; }. Add class Circle extends Shape {}. Write $s = Circle::create(); echo $s->name() . "\n";.
Example solution:
<?php
// LSB example: Shape and Circle
class Shape {
public static function create(): static {
return new static();
}
public function name(): string {
return static::class;
}
}
class Circle extends Shape {}
$s = Circle::create();
echo $s->name() . "\n";
Test yourself
-
Which is true about static members?
- A static property is private to each instance
- A static method can use $this
- self:: refers to the class where the code is written
- static:: always returns the parent class
Show answer
self:: refers to the class where the code is written — Correct. self:: binds to the written class; static:: to the called one.
-
LSB: new static() call
class Product { public string $name; public function __construct(string $name) { $this->name = $name; } public static function create(string $name): static { return new ____ } }Show answer
class Product { public string $name; public function __construct(string $name) { $this->name = $name; } public static function create(string $name): static { return new static($name); } }