This article is mainly for you to introduce in detail PHP trait and its application, with a certain reference value, interested in small partners can refer to
Starting with PHP version 5.4.0, PHP provides a new concept of code reuse, which is trait. Trait it literally means "features", "features", we can understand that using the TRAIT keyword, you can add new features to the classes in PHP.
Familiar with object-oriented knowledge, the common code reuse in software development is inherited and polymorphic two ways. In PHP, you can only implement single inheritance. and trait avoids this. The following is a simple example to illustrate the comparison.
1. Inheritance vs polymorphism vs Trait
There are now two classes of publish.php and answer.php. To add a log function to it, record the actions inside the class. There are several scenarios:
Inheritance
Polymorphic
Trait
1.1. Inheritance
:
The code structure is as follows:
Log.php<?phpclass log{Public Function Startlog () { //echo ...} public Function Endlog () { //echo ...}}
Publish.php<?phpclass Publish extends log{}//Answer.php<?phpclass Answer extends log{}
You can see that inheritance does meet the requirements. But this violates the principle of object-oriented. The relationship between operations and logs (log) such as release (Publish) and Answer (Answer) is not a subclass's relationship to the parent class. So it is not recommended to use this.
1.2. polymorphic
:
Implementation code:
Log.php<?phpinterface log{Public Function Startlog (), Public function endlog ();
Publish.php<?phpclass Publish implements log{Public Function Startlog () { //Todo:implement Startlog () method. } public Function Endlog () { //Todo:implement Endlog () method.}}
Answer.php<?phpclass Answer implements log{Public Function Startlog () { //Todo:implement Startlog () method.} Public Function Endlog () { //Todo:implement Endlog () method.}}
The logging operation should be the same, so the logging implementation in the release (Publish) and Answer (Answer) actions is the same. Obviously, this violates the dry (Don ' t Repeat yourself) principle. So it is not recommended to implement this.
1.3. Trait
:
The implementation code is as follows:
Log.php<?phptrait log{Public Function Startlog () { //Echo:} public Function Endlog () { //Echo:}}
Publish.php<?phpclass Publish {use Log;} $publish = new Publish (); $publish->startlog (); $publish->endlog ();
Answer.php<?phpclass Answer {use Log;} $answer = new Answer (); $answer->startlog (); $answer->endlog ();
As you can see, we have implemented code reuse without adding complexity to the code.
1.4. Conclusion
Although the way of inheritance can solve the problem, its thinking violates the principle of object-oriented, it is very rude, and the polymorphic mode is feasible, but it does not conform to the dry principle in software development, and increases the maintenance cost. And the trait way avoids the above shortcomings, the relatively elegant implementation of the code reuse.
2. Scope of trait
Knowing the benefits of trait, we also need to understand the rules in its implementation, first of all the scopes. This is better proof that the implementation code is as follows:
<?phpclass Publish {Use Log, public function dopublish () { $this->publicf (); $this->PROTECTF (); $this->privatef (); }} $publish = new publish (); $publish->dopublish ();
Executing the above code outputs the following results:
Public function
protected function
Private function
It can be found that the scope of the trait is visible within the reference to the trait class. It can be understood that the USE keyword copies the implementation code of trait to a class that references the trait.
3. Precedence of attributes in trait
When it comes to precedence, there must be a contrasting reference, where the reference object refers to the trait class and its parent class.
Use the following code to demonstrate the precedence of attributes in the Trait app:
<?phptrait log{Public Function publicf () { echo __method__. ' Public function '. Php_eol; } protected function Protectf () { echo __method__. ' Protected function '. Php_eol; }}class question{Public Function publicf () { echo __method__. ' Public function '. Php_eol; } protected function Protectf () { echo __method__. ' Protected function '. Php_eol; }}class Publish extends question{use Log, Public function publicf () { echo __method__. ' Public function '. Php_eol; Public Function Dopublish () { $this->publicf (); $this->PROTECTF (); }} $publish = new publish (); $publish->dopublish ();
The output of the above code is as follows:
Publish::p UBLICF Public function
Log::p ROTECTF protected function
From the above example, you can summarize the following priorities in the trait application:
1. The member from the current class overrides the Trait method
The 2.trait covers the inherited method
Class member priority is: Current class >Trait> parent class
4. Insteadof and as Keywords
In a class, you can refer to multiple trait, as follows:
<?phptrait log{public function Startlog () { echo __method__. ' Public function '. Php_eol; } protected function Endlog () { echo __method__. ' Protected function '. Php_eol;} } Trait check{public function Parametercheck ($parameters) { //do sth }}class Publish extends question{< C12/>use Log,check; Public Function Dopublish ($para) { $this->startlog (); $this->parametercheck ($para); $this->endlog (); }}
In the way above, we can refer to multiple trait in a class. When referring to multiple trait, it is easy to go wrong, the most common problem is that if there is a property or method with the same name in the two trait, what should I do? This time you need to use the insteadof and as two keywords. See the implementation code below:
<?phptrait log{public function Parametercheck ($parameters) { echo __method__. ' Parameter check '. $parameters. Php_eol; } Public Function Startlog () { echo __method__. ' Public function '. Php_eol;} } Trait check{public function Parametercheck ($parameters) { echo __method__. ' Parameter check '. $parameters. Php_eol; } Public Function Startlog () { echo __method__. ' Public function '. Php_eol;} } Class publish{use check, log { Check::p arametercheck insteadof log; Log::startlog insteadof Check; Check::startlog as CSL; } Public Function Dopublish () { $this->startlog (); $this->parametercheck (' params '); $this->CSL (); }} $publish = new Publish (); $publish->dopublish ();
Execute the above code and the output is as follows:
Log::startlog Public Function
Check::p arametercheck parameter Checkparams
Check::startlog Public Function
In the literal sense, the INSTEADOF keyword replaces the latter with the former, and the AS keyword gives the substituted method an alias.
When referencing trait, the Use keyword is used, which is also used to refer to namespaces. The difference between the two is that when referencing trait, it is used inside the class.
The above is the whole content of this article, I hope that everyone's study has helped.