Trait in PHP and its application

Source: Internet
Author: User
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.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.