Php 5.4 new code reuse Trait details, 5.4 trait

Source: Internet
Author: User

Php 5.4 new code reuse Trait details, 5.4 trait

Starting from PHP 5.4.0, PHP provides a new concept of code reuse, that is, Trait. Trait literally means "Features" and "Features". We can understand that using the Trait keyword can add new features to classes in PHP.

Anyone familiar with object-oriented knowledge knows that common code reuse methods in software development include inheritance and polymorphism. In PHP, only single inheritance is allowed. Trait avoids this. The following is a simple example of comparison.

1. Inheritance VS polymorphism VS Trait

Now you havePublish.phpAndAnswer.phpThese two classes. You need to add the LOG function to record internal actions of the class. There are several solutions:

  1. Inheritance
  2. Polymorphism
  3. 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{ }

We can see that inheritance does meet the requirements. However, this violates the object-oriented principle. The relationship between operations such as Publish and Answer and logs is not the relationship between sub-classes and parent classes. Therefore, this is not recommended.

1.2. Polymorphism

:

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 operations for logging should be the same. Therefore, the implementation of logging in Publish and Answer actions is the same. Obviously, this violates the DRY (Don't Repeat Yourself) principle. Therefore, this implementation is not recommended.

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();

We can see that code reuse is implemented without increasing the complexity of the Code.

1.4. Conclusion

Although the inheritance method can also solve the problem, its idea violates the object-oriented principle and seems very crude. The polymorphism method is also feasible, but it does not conform to the DRY principle in software development, increased maintenance costs. The Trait method avoids the above shortcomings and achieves code reuse elegantly.

2. Trait Scope

To understand the benefits of Trait, we also need to understand the rules in its implementation. Let's talk about the scope first. The implementation code is as follows:

<?phpclass Publish { use Log; public function doPublish() {  $this->publicF();  $this->protectF();  $this->privateF(); }}$publish = new Publish();$publish->doPublish();

The output result is as follows:

public functionprotected functionprivate function

It can be found that the scope of Trait is visible within the reference of this Trait class. It can be understood that the use keyword copies the Trait implementation code to the class that references the Trait.

3. Priority of attributes in Trait

When it comes to priority, you must have a reference object for comparison. The reference object here references the Trait class and its parent class.

Use the following code to verify the priority of attributes in a Trait application:

<?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 result of the above Code is as follows:

Publish::publicF public functionLog::protectF protected function

Through the above example, we can sum up the priority of the Trait application as follows:

The member from the current class overwrites the trait method.

Trait overwrites the inherited method

The class member priority is:Current class> Trait> parent class

4. Insteadof and As keywords

You can reference multiple Trait instances in a class 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{ use Log,Check; public function doPublish($para) {  $this->startLog();  $this->parameterCheck($para);  $this->endLog(); }}

In the above method, we can reference multiple Trait instances in a class. When multiple Trait instances are referenced, problems may occur. The most common problem is that if two Trait instances have attributes or methods of the same name, what should they do? In this caseInsteadofAndasSee the following implementation code for the two keywords:

<?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::parameterCheck 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();

Run the above Code and the output result is as follows:

Log::startLog public functionCheck::parameterCheck parameter checkparamsCheck::startLog public function

Just as literally,insteadofThe former replaces the latter with the keyword,asKeyword indicates an alias for the replaced method.

When referencing Trait, the use keyword is used, and the use keyword is also used to reference the namespace. The difference between the two is that Trait is used inside the class when being referenced.

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.