魏长东

weichangdong

php的trait用法

/在facebook的php的sdk中 用法就是假如某一个类不让使用delete方法,就会用到这个trait

当这个类被调用delete这个方法的时候,就会触发trait。

还有fb的类 set某个值的时候,会调用__set方法,这个时候,使用trait,会对需要set的key和value做下

检查判断

trait myTrait{
    function traitMethod1(){
        echo "no this func 1\n";
    }
    function traitMethod2(){
        echo "no this func 2\n";
    }

}

//然后是调用这个traits,语法为:
class myClass{
    use myTrait;
}

//这样就可以通过use myTraits,调用Traits中的方法了,比如:
$obj = new myClass();
$obj->traitMethod1();
$obj->traitMethod2(); 

run result:

no this func 1 no this func 2

接下来,我们探究下为什么要用traits,举个例子,比如有两个类,分别为business(商务者)和Individual(个人),它们都有地址的属性,传统的做法是,再抽象出一个这两个类都共同有特性的父类,比如client,在client类中设置访问属性address,business和individual分别继承之,如下代码:

// Class Client  
class Client  {  
    private $address;  
    public getAddress() {  
        return $this->address;  
    }       
    public setAddress($address) {  
        $this->address = $address;    
    }  
}  
      
class Business extends Client{  
    //这里可以使用address属性  
}  

// Class Individual  
class Individual extends Client{  
//这里可以使用address属性  
}  

但假如又有一个叫order类的,需要访问同样的地址属性,那怎么办呢?order类是不好继承client类的(因为两个类 风牛马不相及,可能order类和client类就一个地址属性可以共用,但是别的client一系列属性方法都和order没啥关系,如果继承,会很诡异)。这个时候traits就派上用场了,可以定义一个traits,用来定义这些公共属性。

// Trait Address
trait Address{
    private $address;
    public function getAddress() {
        eturn $this->address;
    }
    public function setAddress($address) {
        $this->address = $address;
    }
}
// Class Business
class Business{
    use Address;
    // 这里可以使用address属性
}
// Class Individual
class Individual{
    use Address;
    //这里可以使用address属性
}
// Class Order
class Order{
    use Address;
    //这里可以使用address属性
}    
$wcd=new Order;
$wcd->setAddress('beijing');
echo $wcd->getAddress();
echo "<br />";
$wcd=new Individual;
$wcd->setAddress('shanghai');
echo $wcd->getAddress();