ThinkPHP 您现在的位置是:首页 > 开发笔记 > ThinkPHP

Trait和软删除

来源:惠达浪原创 发布时间:2019-05-21 最后更新:2019-05-21 6687已围观

摘要前不久,使用ThinkPHP 5.1中的软删除时,发现并不是太好用,于是对软删除做了进一步的研究,总结出一些经验和技巧,在这里记录一下。在技巧中,关于trait的应用引起了我的注意。

不久前,在写ThinkCMF的留言板插件时,使用了软删除,这个由ThinkPHP提供的功能,以便可以使用ThinkCMF后台的回收站机制。可是在使用的过程中发现了一些问题,虽然后来解决了,但很是不爽,在此把一些知识和经验写下来,也算是一个学习吧。

Trait

软删除使用了PHP的 trait 机制,虽然以前就知道,但这次又加强了一些认识。首先来看看官方的说明:

自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

怎么样?看懂了吗?是不是太奥妙了?反正我是没看懂,但你得承认,这就叫科学,知道不!来,看个大神的解释吧:

PHP面向对象是单继承的,无法同时从两个或以上的基类继承属性或方法。从PHP 5.4起, Traits(构件类)技术出现,使多继承成为现实!

虽然还是不太明了,但是,你看到关键字了吗?多继承!没错,就是为了这个。那么,什么是多继承?我是这样理解的:

当一个类要继承父类的时候,你只能继承一个,所以这个类就有了父亲的技能。但是,就它爹那点儿能耐,混社会也不够用啊,怎么办?上学!去学校学习本领。学校的老师虽然不是它父亲,但也得听老师的话不是。那么怎么确认和老师的关系呢?trait就是。这下好办了,老师多的是,按个trait,本事就学来了!然后还不会乱了继承关系是不是。当然,老师能教这个学生,也可以教别的学生,所以不同的类虽然可以有不同的父类,但都可以trait同一个老师啊!

所以,严格上来说,trait不是多继承,只是引用了其它类的功能而已。使用时要注意:

1、Trait类的声明使用 trait 关键字。

2、通过使用 use 关键字引用Trait类

3、Trait类不能直接实例化。

实例演示一下吧:

trait MathTeacher
{
    public function work()
    {
        return '数学老师教我乘法口诀!';
    }
}

trait ChineseTeacher
{
    public function work()
    {
        return '语文老师教我写论文!';
    }
}

class Father
{
    public function work()
    {
        return '爸爸教我搬砖头!';
    }
}

class Child extends Father
{
    public function work()
    {
        return '我想当程序员!';
    }
}

上边是4个定义,两个 trait 类,一个父类,最后是孩子类。每个类都有一个方法 work,来看一下它们是如何运转的。实例化并运行:

$mySelf = new Child();
echo $mySelf->work();

// 我想当程序员!

这没问题吧,很容易理解吧,孩子有自己的想法,当爹的肯定管不了。(子类方法重写父类的方法)我们看看,孩子有自己的想法,当老师的能不能管。把Child类改成这样:

class Child extends Father
{
    use ChineseTeacher;

    public function work()
    {
        return '我想当程序员!';
    }
}

// 我想当程序员!

注意,这里使用use,引用了trait类。结果还是没变,事实证明,当一个人有思想的时候,谁也左右不了他!那么,如果他是个没主意的人呢?把Child类改成这样,来看看:

class Child extends Father
{
    use ChineseTeacher;
}

// 语文老师教我写论文!

输出结果出来了,竟然执行的不是父类方法,是trait老师的方法!为啥呢?因为官方声明中有这样一句:

从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

用普通话翻译就是:自己的方法 > trait 的方法 > 父类的方法,这就是优先级。

说到这儿,都是方法名完全相同的情况,如果方法名不重名,会怎么样呢?哎呀我去!你要真是这样想的,快别看了,听爸爸的话,去搬砖吧,程序员这行你真干不了。

很赞哦! (452)


站点信息

  • 网站平台ThinkCMF 5.1.5
  • PHP版本:7.3.31
  • QQ交流群: 惠达浪技术交流