ZetCode

PHP Traits

last modified October 22, 2026

In this article, we show how to use traits in PHP. Traits are a mechanism for code reuse in PHP, allowing developers to include methods in multiple classes without using inheritance. Traits are particularly useful for sharing functionality across unrelated classes.

Main Features of PHP Traits

Traits are declared using the trait keyword and can be included in classes using the use keyword.

Basic Usage of Traits

The following example demonstrates how to define and use a trait in PHP.

main.php
<?php

trait Hello
{
    public function sayHello()
    {
        echo "Hello!";
    }
}

class Greeting
{
    use Hello;
}

$greeting = new Greeting();
$greeting->sayHello();

In this program, the Hello trait is defined with a sayHello method. The Greeting class includes the Hello trait using the use keyword and calls the sayHello method.

$ php main.php
Hello!

Multiple Traits

The following example demonstrates how to use multiple traits in a single class.

main.php
<?php

trait Hello
{
    public function sayHello()
    {
        echo "Hello!\n";
    }
}

trait Today
{
    public function showToday()
    {
        echo date("Y-m-d H:i:s\n");
    }
}

class Greeting
{
    use Hello;
    use Today;
}

$greeting = new Greeting();
$greeting->sayHello();
$greeting->showToday();

In this program, the Greeting class includes both the Hello and Today traits. Then it calls methods from both traits.

$ php main.php
Hello!
2025-02-17 11:27:35

Conflict Resolution

The following example demonstrates how to resolve conflicts when two traits have methods with the same name.

main.php
<?php

trait Loggable {
    public function log($message) {
        echo "Loggable: $message\n";
    }
}

trait Notifiable {
    public function log($message) {
        echo "Notifiable: $message\n";
    }
}

class User {
    use Loggable, Notifiable {
        Loggable::log insteadof Notifiable; 
        Notifiable::log as notify;
    }

    public function create() {
        $this->log("User created.");
        $this->notify("Welcome, new user!");
    }
}

$user = new User();
$user->create();

In this program, the User class includes both the Loggable and Notifiable traits, which have conflicting log methods. The conflict is resolved using the insteadof and as keywords.

$ php main.php
Loggable: User created.
Notifiable: Welcome, new user!

Traits with Properties

The following example demonstrates how to define and use properties in traits.

main.php
<?php

trait Loggable {
    protected $logFile = "log.txt";

    public function log($message) {
        file_put_contents($this->logFile, $message . "\n", FILE_APPEND);
    }
}

class User {
    use Loggable;

    public function create() {
        $this->log("User created.");
    }
}

$user = new User();
$user->create();

In this program, the Loggable trait defines a $logFile property and a log method. The User class includes the Loggable trait and uses the log method to write to the log file. Each class that uses a trait gets its own copy of the trait's properties.

$ php main.php
$ cat log.txt
User created.

In the following program, we have two traits: HelloMessage and ColorMessage.

main.php
<?php

trait HelloMessage
{
    public function hello(): void
    {
        echo "Hello there!\n";
    }
}


trait ColorMessage
{
    public function showColorMessage($message, $color = 'default'): void
    {
        $colors = [
            'default' => "\033[0m",    // Default color
            'red' => "\033[31m",      // Red
            'green' => "\033[32m",    // Green
            'yellow' => "\033[33m",   // Yellow
            'blue' => "\033[34m",     // Blue
        ];

        $colorCode = $colors[$color] ?? $colors['default'];
        echo $colorCode . $message . "\n" . "\033[m";
    }
}

class Info
{
    use HelloMessage;
    use ColorMessage;
}

$info = new Info();

$info->hello();

$info->showColorMessage('Hello there!');
$info->showColorMessage('Hello there!', 'green');
$info->showColorMessage('Hello there!', 'blue');

The HelloMessage prints a simple hello message while the ColorMessage takes a message parameter and prints it in color.

public function showColorMessage($message, $color = 'default'): void
{
    $colors = [
        'default' => "\033[0m",    // Default color
        'red' => "\033[31m",      // Red
        'green' => "\033[32m",    // Green
        'yellow' => "\033[33m",   // Yellow
        'blue' => "\033[34m",     // Blue
    ];

    $colorCode = $colors[$color] ?? $colors['default'];
    echo $colorCode . $message . "\n" . "\033[m";
}

We can choose from the given color names or a default one is chosen.

class Info
{
    use HelloMessage;
    use ColorMessage;
}

The Info class uses both traits so it can call both hello and showColorMessage methods.

$ php main.php
Hello there!
Hello there!
Hello there!
Hello there!

On a terminal that supports ANSI escape codes, the last three lines appear in default, green, and blue colors.

Static Members and Abstract Methods

A trait can declare static properties and methods, and abstract methods that the using class must implement.

static_abstract.php
<?php

trait Counter
{
    private static int $count = 0;

    public static function increment(): int
    {
        return ++self::$count;
    }

    abstract public function name(): string;

    public function describe(): string
    {
        return $this->name() . " (" . self::$count . ")";
    }
}

class Apple
{
    use Counter;

    public function name(): string
    {
        return "Apple";
    }
}

class Pear
{
    use Counter;

    public function name(): string
    {
        return "Pear";
    }
}

Apple::increment();
Apple::increment();
Pear::increment();

echo (new Apple)->describe(), "\n";
echo (new Pear)->describe(), "\n";

The name method is abstract, so every class using the trait must define it. The static $count property is not shared: Apple and Pear each get their own copy of it, which is why the two counters differ.

$ php static_abstract.php
Apple (2)
Pear (1)

Constants in Traits

Since PHP 8.2, traits can define constants.

constants.php
<?php

trait Config
{
    public const VERSION = '1.2';

    public function version(): string
    {
        return self::VERSION;
    }
}

class App
{
    use Config;
}

echo (new App)->version(), "\n";
echo App::VERSION, "\n";

The constant becomes a member of the class that uses the trait, so it can be accessed as App::VERSION. Constants cannot be accessed through the trait name itself; Config::VERSION is an error.

$ php constants.php
1.2
1.2

Source

PHP Traits - Documentation

In this article, we have shown how to use traits in PHP for code reuse. Traits are a powerful tool for sharing functionality across unrelated classes without using inheritance.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all PHP tutorials.