Before PHP 5.4, the way PHP object-oriented needed to reuse code was to use class inheritance. However, PHP only supports single inheritance, and in dealing with more complex business logic, single inheritance is difficult.
Use scenarios of trait
For example, the following application scenarios:
class Person { public function eat() { echo "I'm human. I can eat.<br />"; } } class GuoJing extends Person { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } class XiaoFeng extends Person { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } }
Both Guojing and XiaoFeng classes inherit from Person and share the same Kungfu method. Obviously, we can't write this Kungfu method to Person class. Otherwise, any passer-by A inherits the Person class and has Kungfu skills.
Trait can solve this problem:
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } class Person { public function eat() { echo "I'm human. I can eat.<br />"; } } class GuoJing extends Person { use Tool; } class XiaoFeng extends Person { use Tool; } $guojing = new GuoJing(); $xiaofeng = new XiaoFeng(); $guojing->kungfu(); $xiaofeng->kungfu();
The results are as follows:
Eighteen feet of dragon! Eighteen feet of dragon!
Method/attribute rewriting
If the methods or attributes in the Trait class, base class and this class have the same name, which one will ultimately prevail?
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } class Person { public function eat() { echo "I'm human. I can eat.<br />"; } public function kungfu() { echo "Not everyone knows how to work.<br />"; } } class GuoJing extends Person { use Tool; public function kungfu() { echo "In addition to the eighteen palms of the dragon, I also know the Nine Yin Sutra!<br />"; } } class XiaoFeng extends Person { use Tool; } $guojing = new GuoJing(); $guojing->kungfu();
Result:
In addition to the eighteen palms of the dragon, I also know the Nine Yin Sutra!
The result of annotating the kungfu method of this class is as follows:
Eighteen feet of dragon!
When a method or attribute has the same name, the method in the current class overrides the method of trait, and the method of trait overrides the method in the base class.
Combining multiple trait s
When multiple trait s have methods/attributes of the same name, errors are reported:
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } trait Skill { public function kungfu() { echo "Thick internal force is repaired as<br />"; } } class GuoJing { use Tool, Skill; } $guojing = new GuoJing(); $guojing->kungfu();
Fatal error: Trait method kungfu has not been applied, because there are collisions with other trait methods on GuoJing
Solution: Use insteadof and as to resolve conflicts
insteadof: Replace one method with another
as: Alias the method
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } trait Skill { public function kungfu() { echo "Thick internal force is repaired as<br />"; } } class XiaoFeng { use Tool, Skill { Skill::kungfu insteadof Tool; Skill::kungfu as ability; } } $xiaofeng = new XiaoFeng(); $xiaofeng->ability();
Thick internal force is repaired as
Access control of trait method
as keywords can modify access control of methods
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } class XiaoFeng { use Tool { Tool::kungfu as protected ability; // Modify method access control and alias } } $xiaofeng = new XiaoFeng(); $xiaofeng->ability();
Report errors:
Fatal error: Uncaught Error: Call to protected method XiaoFeng::ability() from context
Trait portfolio
Trait can also combine Trait, while it supports Abstract methods, static attributes, and static methods.
<?php trait Tool { public function kungfu() { echo "Eighteen feet of dragon!<br />"; } } trait Feature{ use Tool; abstract public function dream(); public static function character() { echo "Lei Lei and Hao Xiong <br />"; } } class XiaoFeng { use Feature; public function dream() { echo "Make it clear: Who am I? <br />"; } } $xiaofeng = new XiaoFeng(); $xiaofeng->kungfu(); XiaoFeng::character(); $xiaofeng->dream();
Result:
Eighteen feet of dragon! Lei Lei and Hao Xiong Make it clear: Who am I?