PHP中Trait的使用总结

在Laravel中有好多 Trait的使用 感觉很有意思,由于php是单继承的语言 无法同时继承多个基类 但是可以使用 Trait 通过 Trait 可以很方便的实现代码的复用 类似继承的效果。
注意:Trait 不能实例化

示例一

<?php
    trait MyTime{
        public $is_flag=123;
        protected $is_show=0;
        private $is_now=233;
        /**
         * 比如简单的定义一个方法就是获取当前时间一天后的
         */
        public function getTime(){
            return date('Y-m-d H:i:s',time()+3600*24);
        }
    }

    class HelpTime{
        //使用use关键字
        use MyTime;
        public function test(){
            echo $this->is_show."<br/>";
            echo $this->is_flag."<br/>";
            echo $this->is_now."<br/>";
            echo $this->getTime();
        }
    }

    $help=new HelpTime();
    $help->test();
>

以上输出结果

123
0
233
2016-10-21 16:41:22

从上面结果可以看出如果使用use 关键字引入了一个trait 就会拥有它里面的所有属性和方法 包括私有 保护的 可以直接使用

如果需要引入多个Trait可以使用逗号隔开

use Trait1,Trait2;

示例二

<?php
    trait Human{
        public function eat(){
            echo "human eating";
        }
        public function sleep(){
            echo "human sleep";
        }
    }
    class Father{
        public function eat(){
            echo "father eating";
        }
        public function sleep(){
            echo "father sleep";
        }
    }
    class Son extends Father{
        use Human;
        public function eat(){
            echo "son eating";
        }
    }
    $son=new Son();
    $son->eat();
    $son->sleep();
>

输出结果

son eating
human sleep

这个比较有意思了,当类中和基类和trait中存在同名的方法时候 当前类的方法会覆盖基类覆盖 Trait,而同时Trait中的会覆盖基类 这种情况同样适用于变量

示例三

<?php
    trait Test1{
        public function sayHello(){
            echo "test1 say hello";
        }
    }
    trait Test2{
        public function sayHello(){
            echo "test2 say hello";
        }
    }
    class Test3{
        use Test1,Test2;
    }
?>

当适用的多个Trait中含有重名的方法时候会报错

Fatal error: Trait method sayHello has not been applied, because there are collisions with other trait methods on Test3

网上给出的解决办法 适用 insteadofas 来解决 insteadof的作用是使用前面的方法代替后面另外一个方法 而as的作用是给方法取个别名

<?php
    trait Test1{
        public function sayHello(){
            echo "test1 say hello";
        }
    }
    trait Test2{
        public function sayHello(){
            echo "test2 say hello";
        }
    }
    class Test3{
        use Test1,Test2 {
            Test1::sayHello insteadof Test2;
            Test2::sayHello as test2sayhello;
        }
    }
    $test3=new Test3();
    $test3->sayHello();
    $test3->test2sayhello();
>

上面这个输出结果

insteadof 那一句的作用就是使用Test1中的sayHello方法替代Test里的sayHello方法
as 那一句的作用就是直接给Test2中的sayHello方法取了个别名叫 test2sayhello
test1 say hello
test2 say hello
php
本作品采用《CC 协议》,转载必须注明作者和本文链接
微信公众号:码咚没 ( ID: codingdongmei )
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 1

看很多框架的trait用于model定义常规操作的方法,例如CRUD的基本操作,API的常规方法定义等等,真是个好东西。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!