CodeBlanks Logo Icon CodeBlanks

Summary - Traits

PHP course · Intermediate · Lesson 64/115

Build logging-capable classes with trait, use and multiple traits.

Summary: Traits

In this group you learned traits. In short:

  • You declare a reusable method set with trait Name { ... }.
  • Inside a class, use Name; includes the trait and injects its methods.
  • use A, B; combines multiple traits.
  • On same-name method conflicts, insteadof picks one and as aliases another.
  • A trait is horizontal reuse; inheritance is a vertical 'is-a' relationship.

Exercise A logging-capable UserService class

Define a Logger trait: its public function log(string $msg): string method does return "[LOG] " . $msg;. Define a Tagger trait: its public function tag(string $t): string method does return "#" . $t;. Then a UserService class uses both with use Logger, Tagger;. Create an instance with $s = new UserService() and call echo $s->log("signin") . "\n" and echo $s->tag("admin") . "\n".

Show example solution
Write trait Logger { ... } and trait Tagger { ... }. Add class UserService { use Logger, Tagger; }. With $s = new UserService(); call log() and tag().
Example solution:
<?php
// Combine Logger and Tagger traits in the UserService class
trait Logger {
    public function log(string $msg): string {
        return "[LOG] " . $msg;
    }
}

trait Tagger {
    public function tag(string $t): string {
        return "#" . $t;
    }
}

class UserService {
    use Logger, Tagger;
}

$s = new UserService();
echo $s->log("signin") . "\n";
echo $s->tag("admin") . "\n";

Tips for using traits

A few tips when using traits:

  • A trait cannot be instantiated with new; it is only included via use.
  • Keep traits small and single-responsibility; don't cram dozens of methods into one.
  • A trait property is injected into the class; watch for collisions.
  • Prefer inheritance for a real 'is-a' relationship; traits are for sharing behavior.

The design question 'is this a ...' versus 'can this ...' guides your choice.

Test yourself

  1. What is the correct syntax to add both Logger and Notifier to a class?

    • use Logger extends Notifier;
    • extends Logger, Notifier;
    • implements Logger, Notifier;
    • use Logger, Notifier;
    Show answer

    use Logger, Notifier; — Correct. use Logger, Notifier; joins two traits with a comma and includes them in the class.

  2. Match the keyword to its job

    trait
    reusable method set
    use
    include trait in class
    insteadof
    pick conflicting method
    as
    rename a method
  3. Alias a method with as

    trait Printer {
        public function output(): string {
            return "output";
        }
    }
    
    class Report {
        use Printer {
            output ____ asText;
        }
    }
    
    $r = new Report();
    echo $r->asText() . "\n";
    Show answer
    trait Printer {
        public function output(): string {
            return "output";
        }
    }
    
    class Report {
        use Printer {
            output as asText;
        }
    }
    
    $r = new Report();
    echo $r->asText() . "\n";

All lessons in Intermediate