W3docs

insteadof

The "insteadof" keyword is used in PHP to specify that one trait should be used instead of another trait for a given method. In this article, we will explore

The PHP insteadof Keyword

insteadof is a PHP keyword used inside a use block to resolve a method conflict between two or more traits. When a class uses several traits that each define a method with the same name, PHP cannot decide which one wins and throws a fatal error. insteadof tells PHP which trait's method to keep and which trait's method to discard.

This page explains the conflict it solves, its exact syntax, how it pairs with the as keyword to keep the "losing" method, and the gotchas worth knowing.

The problem insteadof solves

A trait is a reusable block of methods that gets copied into a class at compile time. If two traits define a method with the same name and a class uses both, PHP has no way to pick one. The result is a fatal collision error:

<?php

trait FileLogger {
  function log() { echo "Writing to a file."; }
}
trait DatabaseLogger {
  function log() { echo "Writing to the database."; }
}

class Service {
  use FileLogger, DatabaseLogger; // No conflict resolution
}

// PHP Fatal error: Trait method DatabaseLogger::log has not been
// applied as Service::log, because of collision with FileLogger::log

The class never even gets created — this is a compile-time error, not a runtime one. insteadof is how you tell PHP which method to apply.

Syntax

insteadof is written inside the curly-brace block of a use statement:

use TraitWeKeep, TraitWeDrop {
    TraitWeKeep::methodName insteadof TraitWeDrop;
}

Read it as: "use TraitWeKeep's methodName instead of TraitWeDrop's." The trait named after insteadof has its version of that method removed from the class.

<?php

trait FileLogger {
  function log() { echo "Writing to a file."; }
}
trait DatabaseLogger {
  function log() { echo "Writing to the database."; }
}

class Service {
  use FileLogger, DatabaseLogger {
    FileLogger::log insteadof DatabaseLogger;
  }
}

$service = new Service();
$service->log();
// Output: Writing to a file.

Resolving against more than one trait

If three or more traits collide, list every trait you want to exclude after insteadof, separated by commas:

<?php

trait Json    { function format() { echo "JSON output"; } }
trait Xml      { function format() { echo "XML output"; } }
trait Csv      { function format() { echo "CSV output"; } }

class Report {
  use Json, Xml, Csv {
    Json::format insteadof Xml, Csv;
  }
}

$report = new Report();
$report->format();
// Output: JSON output

Keeping the other method with as

insteadof discards a method — but often you don't want to lose it, you just want it under a different name so both are available. That's what the as keyword does: it aliases the excluded method to a new name so it survives the conflict resolution.

<?php

trait FileLogger {
  function log($msg) { return "[file] $msg"; }
}
trait DatabaseLogger {
  function log($msg) { return "[db] $msg"; }
}

class Service {
  use FileLogger, DatabaseLogger {
    FileLogger::log insteadof DatabaseLogger;  // FileLogger::log becomes log()
    DatabaseLogger::log as logToDb;            // DatabaseLogger::log survives as logToDb()
  }
}

$service = new Service();
echo $service->log("started"), "\n";      // [file] started
echo $service->logToDb("started"), "\n";  // [db] started

insteadof and as are almost always used together: insteadof picks the winner, as rescues the loser under an alias. The as keyword can also change a method's visibility (for example FileLogger::log as protected;).

Gotchas

  • insteadof only resolves name collisions. If the two methods don't share a name, there is no conflict and insteadof is unnecessary.
  • You must reference a method that actually exists in the named trait, using the Trait::method syntax. A typo produces a fatal error.
  • It does not merge behavior. The excluded method is simply not applied; insteadof never calls both methods.
  • A child class still wins over a trait. Method resolution order is: methods defined in the class itself override trait methods, and trait methods override inherited (parent-class) methods.

When to use it

Reach for insteadof whenever you compose a class from multiple traits and two of them happen to expose the same method name — common when mixing third-party traits you don't control. Combined with as, it lets you compose behavior from independent traits without renaming their source code, keeping your classes modular and conflict-free.

Practice

Practice
What does the 'insteadof' keyword do in PHP?
What does the 'insteadof' keyword do in PHP?
Was this page helpful?