Home Quizzes Leaderboard Competitions Learn Hire Us
About Contact
Log In Sign Up
Learn PHP Traits & Advanced OOP

Traits & Advanced OOP

⏱ 20 min read read
Traits --- PHP's Solution to Multiple Inheritance:

PHP only supports single inheritance (one parent class). Traits let you
share methods across unrelated classes without inheritance.

trait Timestamps {

private DateTime $createdAt;

private DateTime $updatedAt;

public function getCreatedAt(): DateTime { return $this->createdAt;
}

public function touch(): void { $this->updatedAt = new DateTime();
}

}

class User {

use Timestamps; // ← include the trait

// User now has createdAt, updatedAt, getCreatedAt, touch

}

A class can use multiple traits: use Timestamps, SoftDelete,
Loggable;

Traits solve PHP's single-inheritance limitation.

Traits are like copy-paste at compile time --- they mix methods into
classes.

Traits can have abstract methods that the using class must implement.

Static Methods & Properties:

class Counter {

private static int $count = 0;

public static function increment(): void {

self::$count++;

}

public static function getCount(): int {

return self::$count;

}

}

Counter::increment(); // no object needed

Counter::increment();

echo Counter::getCount(); // 2

Readonly Properties & Classes (PHP 8.1+):

class Money {

public function \_\_construct(

public readonly float $amount,

public readonly string $currency

) {}

}

$price = new Money(9.99, 'USD');

echo $price->amount; // 9.99

// $price->amount = 5; --- ERROR: Cannot modify readonly property

Enums (PHP 8.1+):

enum Status { case Active; case Inactive; case Pending; }

// Backed enum (with values)

enum Color: string { case Red = 'red'; case Blue = 'blue'; }

$s = Status::Active;

$c = Color::from('red'); // Color::Red

echo $c->value; // 'red'
Code Example
<?php

// Trait --- reusable across unrelated classes

trait Timestampable {

private string $createdAt;

private string $updatedAt;

public function initTimestamps(): void {

$this->createdAt = date('Y-m-d H:i:s');

$this->updatedAt = $this->createdAt;

}

public function touch(): void {

$this->updatedAt = date('Y-m-d H:i:s');

}

public function getCreatedAt(): string { return $this->createdAt; }

public function getUpdatedAt(): string { return $this->updatedAt; }

}

trait SoftDeletable {

private bool $deleted = false;

public function delete(): void { $this->deleted = true; }

public function restore(): void { $this->deleted = false; }

public function isDeleted(): bool { return $this->deleted; }

}

class User {

use Timestampable, SoftDeletable; // multiple traits!

public function \_\_construct(public readonly string $name) {

$this->initTimestamps();

}

}

$user = new User('Alice');

echo $user->name . "\n";

echo $user->getCreatedAt() . "\n";

$user->delete();

echo $user->isDeleted() ? "Deleted\n" : "Active\n";

// Static

class IdGenerator {

private static int $next = 1;

public static function generate(): int { return self::$next++; }

}

echo IdGenerator::generate() . "\n"; // 1

echo IdGenerator::generate() . "\n"; // 2

// Enum (PHP 8.1+)

enum Status: string {

case Active = 'active';

case Inactive = 'inactive';

case Pending = 'pending';

public function label(): string {

return match($this) {

Status::Active => 'Active User',

Status::Inactive => 'Inactive User',

Status::Pending => 'Pending Approval',

};

}

}

$s = Status::Active;

echo $s->value . "\n"; // active

echo $s->label() . "\n"; // Active User

?>
← Databases & PDO Namespaces & Autoloading →

Log in to track your progress and earn badges as you complete lessons.

Log In to Track Progress