Menu
Coddy logo textTech

Trait Conflict Resolution

Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 53 of 91.

When two traits define methods with the same name, PHP throws a fatal error. You must explicitly tell PHP how to handle this conflict using the insteadof and as operators.

<?php
trait FileLogger {
    public function log(string $message): void {
        echo "File: $message";
    }
}

trait DatabaseLogger {
    public function log(string $message): void {
        echo "DB: $message";
    }
}

class Application {
    use FileLogger, DatabaseLogger {
        FileLogger::log insteadof DatabaseLogger;
        DatabaseLogger::log as logToDatabase;
    }
}

$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");

Output:

File: Error occurred
DB: Error occurred

The insteadof operator chooses which trait's method to use when there's a conflict. In this example, FileLogger::log wins and becomes the default log() method. The as operator creates an alias, letting you access the other trait's method under a different name.

You can also use as to change a method's visibility:

<?php
trait Greeting {
    public function sayHello(): void {
        echo "Hello!";
    }
}

class Person {
    use Greeting {
        sayHello as private;
    }
}

This makes sayHello() private within the Person class, even though it's public in the trait. Conflict resolution gives you fine-grained control over how trait methods integrate into your classes.

challenge icon

Challenge

Easy

Let's build a notification system where different channels can send messages, but we need to resolve conflicts when multiple traits provide the same method name.

You'll organize your code across four files:

  • EmailNotifier.php — Create a trait called EmailNotifier with a method notify(string $message) that returns "Email: [message]".
  • SmsNotifier.php — Create a trait called SmsNotifier with a method notify(string $message) that returns "SMS: [message]".
  • AlertService.php — Create an AlertService class that uses both traits. Since both traits have a notify() method, you'll need to resolve this conflict:
    • Use EmailNotifier::notify as the default notify() method
    • Create an alias notifyBySms for the SmsNotifier::notify method
    Also add a method notifyAll(string $message) that calls both notification methods and returns them combined on separate lines.
  • main.php — Include all the necessary files and create an AlertService instance. You'll receive one input: a message string. Print three lines:
    • The result of calling notify() with the message
    • The result of calling notifyBySms() with the message
    • The result of calling notifyAll() with the message

This demonstrates how insteadof resolves which trait's method wins when there's a naming conflict, while as lets you keep access to the other trait's method under a different name.

Try it yourself

<?php
require_once 'AlertService.php';

// Read input
$message = trim(fgets(STDIN));

// TODO: Create an AlertService instance

// TODO: Print the result of calling notify() with the message

// TODO: Print the result of calling notifyBySms() with the message

// TODO: Print the result of calling notifyAll() with the message
?>
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming