Introduction to Traits
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 51 of 91.
PHP only supports single inheritance - a class can extend just one parent class. But what if you need to share functionality across multiple unrelated classes? This is where traits come in.
A trait is a mechanism for code reuse that lets you define methods and properties that can be inserted into multiple classes. Think of traits as copy-paste at the language level - the code from a trait becomes part of the class that uses it.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
The use keyword inside a class imports the trait's members. Now Article has access to setCreatedAt() and getCreatedAt() as if they were defined directly in the class.
The same trait can be used in completely unrelated classes - a Comment class, a User class, or any other class that needs timestamp functionality. This solves the limitation of single inheritance by allowing horizontal code sharing across your class hierarchy.
Challenge
EasyLet's build a simple greeting system that demonstrates how traits allow you to share functionality across unrelated classes. You'll create a trait that provides a greeting capability, then use it in two completely different classes.
You'll organize your code across three files:
Greetable.php— Create a trait calledGreetablethat provides greeting functionality. The trait should have:- A private property
$greeting(string) - A method
setGreeting(string $greeting)that stores the greeting message - A method
greet()that returns the greeting message
- A private property
Person.php— Create aPersonclass that uses theGreetabletrait. Include the trait file and use constructor promotion to define a public$nameproperty. In the constructor, callsetGreeting()to set the greeting to"Hello, I'm [name]".Robot.php— Create aRobotclass that also uses theGreetabletrait. Include the trait file and use constructor promotion to define a public$modelproperty. In the constructor, callsetGreeting()to set the greeting to"Beep boop, I am model [model]".
In main.php, include both class files. You'll receive two inputs: a person's name and a robot's model number. Create instances of both classes and print their greetings on separate lines.
This demonstrates the power of traits — Person and Robot are completely unrelated classes with no shared parent, yet they both gain the same greeting functionality through the trait. Each class customizes how it uses that functionality in its own way.
Cheat sheet
A trait is a mechanism for code reuse that allows you to share methods and properties across multiple unrelated classes, solving PHP's single inheritance limitation.
Define a trait using the trait keyword:
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
Use a trait in a class with the use keyword:
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
The trait's methods and properties become part of the class as if they were defined directly in it. Multiple unrelated classes can use the same trait to share functionality horizontally across your class hierarchy.
Try it yourself
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Read input
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Create a Person instance with the given name
// TODO: Create a Robot instance with the given model
// TODO: Print the Person's greeting
// TODO: Print the Robot's greeting (on a new line)
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern