---
# System prepended metadata

title: '[php筆記]trait教學'
tags: [trait, PHP]

---

# [php筆記]trait教學
###### tags: `PHP` `trait`
2021/10/19

參考:[Day 04：trait 的使用](https://ithelp.ithome.com.tw/articles/10213816)


## 覆蓋優先級別
     1. **屬性無法覆蓋**
     1. 當前class成員方法覆蓋trait成員方法
     1. trait成員方法則覆蓋了被繼承的成員方法

## Trait 也能組合Trait，Trait中支援抽象方法、靜態屬性及靜態方法
(部分參考:https://tw511.com/a/01/5018.html)
```
trait Hello {
    public function sayHello() {
        echo "Hello 我是周伯通n";
    }
}
 
trait World {
    use Hello;
    public function sayWorld() {
        echo "hello worldn";
    }
    abstract public function getWorld();
    public function inc() {
        static $c = 0;
        $c = $c + 1;
        echo "$cn";
    }
    public static function doSomething() {
        echo "Doing somethingn";
    }
}
```


## 多個trait同時使用
使用`,` use 起來即可
```php=
class MyClass
{
    use Trait1, Trait2;
    //...
}
```


### 需要特別注意是否有衝突的問題
不然會直接報錯
對於衝突的方法，直接用insteadof指定誰取代誰
參考:
https://stackoverflow.com/a/31963156)
https://www.php.net/manual/zh/language.oop5.traits.php
```php=
class MyClass {
    use TraitA, TraitB, TraitC, TraitD {
        TraitA::myFunc insteadof TraitB, TraitC, TraitD;
    }
    //...
}
```


## 像繼承那樣調用Trait函數的方法

參考
[How to override trait function and call it from the overridden function?](https://stackoverflow.com/questions/11939166/how-to-override-trait-function-and-call-it-from-the-overridden-function)

解決方法就是直接設定別名

```php=
trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as protected traitcalc;
    }

    function calc($v) {
        $v++;
        return $this->traitcalc($v);
    }
}
```