Xiao Feng and Guo Jing teach you how to learn PHP Trait

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? 

Source Download

Source warehouse links

Keywords: PHP Attribute

Added by Thierry on Wed, 12 Jun 2019 02:05:14 +0300