← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Traits

php PHP 5.4+ Intermediate

Also Known As

PHP traits trait keyword horizontal reuse

TL;DR

Reusable code blocks that can be mixed into any class, providing horizontal code reuse without inheritance.

Explanation

PHP traits are a mechanism for code reuse in single-inheritance languages. A trait can contain methods (including abstract ones) and properties, and is included in a class with use TraitName. Conflicts between multiple traits are resolved explicitly. Traits are useful for cross-cutting concerns like logging, timestamping, or soft deletion. However, heavy trait usage can obscure where methods come from, increase coupling, and complicate testing — prefer composition (injected objects) for behaviour that varies, reserving traits for truly horizontal concerns.

Diagram

flowchart TD
    subgraph Without_Traits
        BASE2[Base class] -->|only one parent| CHILD[Child class<br/>cannot inherit from two classes]
    end
    subgraph With_Traits
        T1[trait Timestampable<br/>created_at updated_at]
        T2[trait SoftDeletable<br/>deleted_at restore]
        T3[trait Auditable<br/>log changes]
        MODEL2[Model uses T1 T2 T3<br/>all three behaviours]
        T1 & T2 & T3 --> MODEL2
    end
    subgraph Conflict_Resolution
        CONFLICT[Two traits same method] --> INSTEADOF[insteadof keyword<br/>choose which wins]
        CONFLICT --> ALIAS[alias keyword<br/>rename one method]
    end
style MODEL2 fill:#238636,color:#fff
style T1 fill:#1f6feb,color:#fff
style T2 fill:#6e40c9,color:#fff

Common Misconception

Traits are a clean solution to the lack of multiple inheritance. Traits enable code reuse but create hidden coupling — a class using a trait implicitly depends on its internal details. Traits with state (properties) are especially fragile. Prefer composition via constructor injection for most reuse scenarios.

Why It Matters

Traits solve the horizontal code reuse problem PHP's single-inheritance model creates — you can compose behaviours like Timestampable, SoftDelete, or Auditable into any class without inheritance chains. Overusing them creates hidden coupling, but used well they eliminate duplication.

Common Mistakes

  • Using traits as a substitute for proper abstraction — if the behaviour belongs in a service or base class, use that instead.
  • Defining properties in traits that conflict with the using class — PHP raises a fatal error.
  • Importing multiple traits with conflicting method names without resolving the conflict with insteadof.
  • Hiding business logic in traits where it is hard to discover — traits are best for cross-cutting technical concerns.

Avoid When

  • Do not use traits to work around poor class hierarchy design — if two classes share a trait's entire interface, they probably need a shared base class or interface.
  • Avoid traits with more than one clear responsibility — they become hidden coupling between unrelated classes.

When To Use

  • Use traits to share behaviour across classes that cannot share a common parent — horizontal code reuse.
  • Use traits for cross-cutting concerns like logging, serialisation helpers, or timestamp management.

Code Examples

✗ Vulnerable
// Code duplication across unrelated classes:
class User {
    public function getCreatedAt(): DateTime { return $this->createdAt; }
    public function getUpdatedAt(): DateTime { return $this->updatedAt; }
}
class Product {
    public function getCreatedAt(): DateTime { return $this->createdAt; } // Duplicated
    public function getUpdatedAt(): DateTime { return $this->updatedAt; } // Duplicated
}

// With trait:
trait HasTimestamps {
    public function getCreatedAt(): DateTime { return $this->createdAt; }
    public function getUpdatedAt(): DateTime { return $this->updatedAt; }
}
class User { use HasTimestamps; }
class Product { use HasTimestamps; }
✓ Fixed
// Trait for shared behaviour across unrelated classes
trait Timestamps {
    public ?\DateTimeImmutable $createdAt = null;
    public ?\DateTimeImmutable $updatedAt = null;

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

trait SoftDeletable {
    public ?\DateTimeImmutable $deletedAt = null;
    public function delete(): void    { $this->deletedAt = new \DateTimeImmutable(); }
    public function restore(): void   { $this->deletedAt = null; }
    public function isDeleted(): bool { return $this->deletedAt !== null; }
}

class Order    { use Timestamps, SoftDeletable; }
class Product  { use Timestamps; }

Tags


Added 15 Mar 2026
Edited 31 Mar 2026
Views 32
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 1 ping M 0 pings T 1 ping W 2 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Perplexity 9 Amazonbot 8 Ahrefs 5 Google 4 Unknown AI 2 ChatGPT 2
crawler 26 crawler_json 4
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use traits for horizontal code reuse (logging, timestamping, soft-delete) across unrelated classes — but prefer composition/interfaces for behaviour that needs to be swappable
📦 Applies To
PHP 5.4+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Identical methods duplicated across multiple classes with no common parent — candidate for trait
Auto-detectable: ✗ No phpcpd phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class Tests: Update

✓ schema.org compliant