PHP Traits
Reusing code across multiple classes
🔧 What are PHP Traits?
Traits are a mechanism for code reuse in PHP. They allow you to share methods across multiple classes without using inheritance, solving the single inheritance limitation in PHP.
<?php
// Simple trait example
trait Greetings {
public function sayHello() {
return "Hello!";
}
}
class User {
use Greetings;
}
$user = new User();
echo $user->sayHello(); // Hello!
?>
Why Use Traits?
Code Reuse
Share methods across unrelated classes
No Inheritance
Avoid complex inheritance hierarchies
Multiple Traits
Use multiple traits in one class
Horizontal Reuse
Share functionality across class trees
🔹 Basic Trait Example
Traits are declared using the trait keyword and included in classes using the use keyword. They provide a simple way to share methods between classes.
<?php
// Define a trait
trait Timestamp {
public function getTimestamp() {
return date('Y-m-d H:i:s');
}
}
// Use trait in a class
class Article {
use Timestamp;
public $title = "My Article";
}
class Comment {
use Timestamp;
public $text = "Great post!";
}
$article = new Article();
$comment = new Comment();
echo "Article: " . $article->getTimestamp() . "<br>";
echo "Comment: " . $comment->getTimestamp();
?>
Output:
Article: 2025-10-14 10:30:45
Comment: 2025-10-14 10:30:45
🔹 Using Multiple Traits
A class can use multiple traits by separating them with commas, combining functionality from different sources into a single class.
<?php
trait Logger {
public function log($message) {
return "LOG: $message";
}
}
trait Validator {
public function validate($data) {
return !empty($data);
}
}
class User {
use Logger, Validator;
public $name;
public function create($name) {
if ($this->validate($name)) {
$this->name = $name;
return $this->log("User $name created");
}
return "Invalid data";
}
}
$user = new User();
echo $user->create("John");
?>
Output:
LOG: User John created
🔹 Trait Method Conflicts
When two traits have methods with the same name, you can resolve conflicts using the insteadof and as operators to specify which method to use.
<?php
trait English {
public function greet() {
return "Hello";
}
}
trait Spanish {
public function greet() {
return "Hola";
}
}
class Person {
use English, Spanish {
English::greet insteadof Spanish;
Spanish::greet as greetSpanish;
}
}
$person = new Person();
echo $person->greet() . "<br>";
echo $person->greetSpanish();
?>
Output:
Hello
Hola
🔹 Changing Method Visibility
You can change the visibility of trait methods when using them in a class, making public methods private or vice versa as needed.
<?php
trait Helper {
public function publicMethod() {
return "This is public";
}
private function privateMethod() {
return "This is private";
}
}
class MyClass {
use Helper {
publicMethod as private;
privateMethod as public makePublic;
}
public function test() {
return $this->publicMethod();
}
}
$obj = new MyClass();
echo $obj->test() . "<br>";
echo $obj->makePublic();
?>
Output:
This is public
This is private
🔹 Traits with Properties
Traits can contain properties as well as methods, allowing you to share both data and behavior across multiple classes.
<?php
trait Counter {
public $count = 0;
public function increment() {
$this->count++;
return $this->count;
}
public function getCount() {
return $this->count;
}
}
class PageView {
use Counter;
}
class ClickTracker {
use Counter;
}
$page = new PageView();
$page->increment();
$page->increment();
$clicks = new ClickTracker();
$clicks->increment();
echo "Page views: " . $page->getCount() . "<br>";
echo "Clicks: " . $clicks->getCount();
?>
Output:
Page views: 2
Clicks: 1
🔹 Traits Composed of Traits
Traits can use other traits, allowing you to build complex functionality by composing simpler traits together in a hierarchical structure.
<?php
trait Name {
public $name;
public function setName($name) {
$this->name = $name;
}
}
trait Email {
public $email;
public function setEmail($email) {
$this->email = $email;
}
}
trait UserInfo {
use Name, Email;
public function getInfo() {
return "Name: {$this->name}, Email: {$this->email}";
}
}
class Account {
use UserInfo;
}
$account = new Account();
$account->setName("Alice");
$account->setEmail("[email protected]");
echo $account->getInfo();
?>
Output:
Name: Alice, Email: [email protected]
🔹 Abstract Methods in Traits
Traits can declare abstract methods that must be implemented by the class using the trait, ensuring required functionality is provided.
<?php
trait Formatter {
abstract public function getData();
public function format() {
$data = $this->getData();
return strtoupper($data);
}
}
class Product {
use Formatter;
private $name = "laptop";
public function getData() {
return $this->name;
}
}
$product = new Product();
echo $product->format();
?>
Output:
LAPTOP
💡 Key Points to Remember:
- Traits enable horizontal code reuse without inheritance
-
Use the
traitkeyword to define traits -
Use the
usekeyword to include traits in classes - A class can use multiple traits
-
Resolve method conflicts with
insteadofandas - Traits can contain properties, methods, and abstract methods
- Traits can use other traits
- Method visibility can be changed when using traits