1. Background
PHP has always been a single-inheritance language from the past to the present. It cannot inherit properties and methods from two base classes at the same time. In order to solve this problem, PHP has the Trait feature.
2. Usage
<?php
//使用trait声明Test类
trait Test{
public function getName() {
echo "hello world";
}
public function getAge() {
echo 18;
}
}
//使用use关键字进行引入
class Ceshi {
use Test;
}
$r = new Ceshi();
$r->getName();
$r->getAge();
As you can see, we have achieved code reuse without increasing code complexity, and it is more elegant.
3. Priority of attributes in Trait
<?php
trait 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 is as follows:
Publish::publicF public function
Log::protectF protected function
Through the above example, the priorities in Trait applications can be summarized as follows:
- Members from the current class override the trait's methods
- Traits override inherited methods
Class member priority is:当前类>Trait>父类
4. Insteadof and As keywords
We know that multiple Traits can be referenced with commas in a class, but what should we do if properties or methods with the same name appear?
At this time, you need to use the Insteadof
two as
keywords
insteadof operator: to clearly specify which conflicting method to use, but this method can only exclude methods with the same name in other traits.
as operator: You can introduce aliases for a method
<?php
Trait One {
public function sayHello()
{
return 'one';
}
}
Trait Two {
public function sayHello()
{
return 'two';
}
}
class Ceshi {
use One, Two {
Two::sayHello insteadof One; //指定要使用的trait
Two::sayHello as twoMethod; //同方法名的trait设置别名
}
}
$rs = new Ceshi();
echo $rs->twoMethod();
//输出:two