← Tilbage til koncepter

Traits

Genbrugelige metoder på tværs af multiple classes uden inheritance

Kategori: Advanced

🎯 Key Points

  • Horisontal code reuse - Del metoder mellem ikke-relaterede klasser
  • Multiple traits per class - En klasse kan bruge flere traits samtidig
  • Conflict resolution - Håndter navnekonflikter mellem traits med insteadof og as
  • Trait composition - Traits kan selv bruge andre traits
  • Abstract methods in traits - Kræv at klassen implementerer bestemte methods
  • Properties in traits - Traits kan definere properties lige som methods
  • Visibility modifiers - Ændr visibility af trait methods med as keyword
  • Method aliasing - Giv trait methods nye navne i klassen
  • Static methods - Traits kan indeholde både instance og static methods
  • Precedence rules - Klasse methods overrider trait methods, trait methods overrider inherited methods

💻 Kode Eksempel

<?php

// Trait with abstract method requirement
trait Timestampable {
    private ?DateTime $createdAt = null;
    private ?DateTime $updatedAt = null;
    
    public function touch(): void {
        $this->updatedAt = new DateTime();
        if ($this->createdAt === null) {
            $this->createdAt = new DateTime();
        }
    }
    
    public function getCreatedAt(): ?DateTime {
        return $this->createdAt;
    }
    
    abstract public function save(): bool;
}

trait SoftDeletes {
    private ?DateTime $deletedAt = null;
    
    public function softDelete(): void {
        $this->deletedAt = new DateTime();
        $this->save();
    }
    
    public function restore(): void {
        $this->deletedAt = null;
        $this->save();
    }
    
    public function isDeleted(): bool {
        return $this->deletedAt !== null;
    }
}

// Using multiple traits with conflict resolution
class Article {
    use Timestampable, SoftDeletes;
    
    private string $title;
    private string $content;
    
    public function __construct(string $title, string $content) {
        $this->title = $title;
        $this->content = $content;
        $this->touch();
    }
    
    public function save(): bool {
        echo "Saving article: {$this->title}\n";
        return true;
    }
}

// Usage
$article = new Article('PHP Traits Guide', 'Content here...');
$article->softDelete();
echo "Deleted: " . ($article->isDeleted() ? 'Yes' : 'No') . "\n";
$article->restore();
echo "Deleted: " . ($article->isDeleted() ? 'Yes' : 'No') . "\n";

💼 Hvornår bruges det?

  • Logging functionality - Del logging methods mellem forskellige klasser uden at alle skal extend en BaseClass
  • Timestamp tracking - Automatisk createdAt og updatedAt felter på models
  • UUID generation - Generer unikke identifiers for entities
  • Authorization checks - Del permission checking logic mellem controllers
  • Soft deletes - Implementer soft delete funktionalitet på database models
  • API response formatting - Standard JSON response methods i API controllers

⭐ Best Practices

  • Brug traits til horisontal funktionalitet der ikke passer ind i klassehierarkiet
  • Undgå at lave traits for store - hold dem fokuserede på én specifik funktionalitet
  • Dokumentér trait dependencies klart hvis en trait kræver bestemte properties eller methods
  • Brug abstract methods i traits til at sikre at klassen implementerer nødvendige methods
  • Vær opmærksom på method name conflicts når du bruger multiple traits
  • Prefer composition (traits) over deep inheritance hierarchies
  • Navngiv traits efter deres funktionalitet med -able suffix (Timestampable, Loggable)
  • Test traits isolated ved at lave test classes der kun bruger den specifikke trait

ℹ️ Quick Info

Kategori
Advanced
Sværhedsgrad
Mellem