Introduction
Traits let you reuse code in different classes. Sometimes, two traits have methods with the same name. Trait conflict resolution helps you decide which method to use.
class ClassName { use TraitA, TraitB { TraitA::methodName insteadof TraitB; TraitB::methodName as newMethodName; } }
<?php trait A { public function hello() { echo "Hello from A\n"; } } trait B { public function hello() { echo "Hello from B\n"; } } class MyClass { use A, B { A::hello insteadof B; } } $obj = new MyClass(); $obj->hello();
<?php trait A { public function hello() { echo "Hello from A\n"; } } trait B { public function hello() { echo "Hello from B\n"; } } class MyClass { use A, B { A::hello insteadof B; B::hello as helloFromB; } } $obj = new MyClass(); $obj->hello(); $obj->helloFromB();
<?php trait Logger { public function log() { echo "Logging from Logger trait\n"; } } trait Debugger { public function log() { echo "Logging from Debugger trait\n"; } } class Application { use Logger, Debugger { Logger::log insteadof Debugger; Debugger::log as debugLog; } } $app = new Application(); $app->log(); $app->debugLog();
insteadof keyword when using traits in PHP?insteadofinsteadof keyword explicitly tells PHP which trait's method to use, resolving the conflict.insteadof = choose method [OK]insteadof to pick one method when names clash [OK]insteadof with asinsteadof renames methodsinsteadof imports all methodsinsteadof in PHP?insteadof keyword to specify which trait's method to use.TraitA::methodName insteadof TraitB; inside the use block.insteadof syntax = use TraitA, TraitB { TraitA::methodName insteadof TraitB; } [OK]insteadof outside the use blockas instead of insteadof for conflict resolutiontrait A {
public function hello() {
return "Hello from A";
}
}
trait B {
public function hello() {
return "Hello from B";
}
}
class MyClass {
use A, B {
B::hello insteadof A;
A::hello as helloFromA;
}
}
$obj = new MyClass();
echo $obj->hello();
echo " - ";
echo $obj->helloFromA();insteadof usageB::hello insteadof A, so hello() calls use trait B's method.as usageA::hello to helloFromA, so $obj->helloFromA() calls trait A's method.insteadof picks B, as renames A [OK]hello() calls trait A's methodas with insteadoftrait X {
public function test() {
return "X";
}
}
trait Y {
public function test() {
return "Y";
}
}
class Demo {
use X, Y {
test insteadof X, Y;
}
}insteadof syntaxX::test insteadof Y;.test insteadof X, Y; without trait prefix, which is invalid syntax.insteadof syntax is incorrect; method must be prefixed by trait name -> Option Binsteadof [OK]insteadof [OK]insteadofuse blockLogger and FileLogger, both with a method log(). You want a class to use FileLogger::log() by default but also keep Logger::log() accessible under the name basicLog(). Which code snippet correctly achieves this?insteadofFileLogger::log() by default, write FileLogger::log insteadof Logger;.asLogger::log() accessible as basicLog(), write Logger::log as basicLog;.insteadof, rename with as [OK]insteadof for default, as to rename [OK]insteadofas without insteadofPass the test and this pattern moves unknown