php关键字-trait

简介: php关键字-trait

介绍

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


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


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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<?php

traitHello{

    publicfunctionecho_hello(){

        echo'hello';

    }

}

traitWorld{

    publicfunctionecho_world(){

        echo'world';

    }

}

 

classA{

    useHello,World;

}

$anewA();

$a->echo_hello();

$a->echo_world();

输出:

trait的应用场景

PHP语言使用一种典型的单继承模型,在这种模型中,我们先编写一个通用的根类,实现基本的功能,然后扩展这个根类,创建更具体的子类,直接从父类继承实现。这叫做继承层次结构,很多编程语言都使用这个模式。大多数时候这种典型的继承模型能够良好运作,但是如果想让两个无关的PHP类具有类似的行为,应该怎么做呢?

Trait就是为了解决这种问题而诞生的。Trait能够把模块化的实现方式注入多个无关的类中,从而提高代码复用,符合DRY(Don’t Repeat Yourself) 原则和面对对象单一职责。

使用场景一:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

traitLogin{

    publicfunctionlogin(){

    }

}

traitRegister{

    publicfunctionregister(){

    }

}

 

classAuth{

    useLogin,Register;

    publicfunctionauth(){

        

    }

}

$anewAuth();

当系统底层的auth验证时,auth类通过use login,use register,使底层验证类有了登录注册功能,实现了代码复用


使用场景二:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

traitSingleton{

    protectedstatic$_instance;

    publicstaticfunctiongetInstance()

    {

        if(! (self::$_instanceinstanceofself) )

        {

            self::$_instancenewstatic(); //new static和new self区别可查看http://www.jb51.net/article/54167.htm

        }

        returnself::$_instance;

    }

}

classA{

    useSingleton;

 

}

classB{

    useSingleton;

 

}

 

$a= A::getInstance();

$b= B::getInstance();

var_dump($a);

var_dump($b);

用trait实现单例模式


trait优先级

一:方法优先级

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

traitTest{

    publicfunctionecho_a(){

        echo'test_a';

    }

}

classA{

    useTest;

    publicfunctionecho_a(){

        echo'a';

    }

}

$anewA();

$a->echo_a();

输出 'a';

traitTest{

    publicfunctionecho_a(){

        echo'test_a';

    }

}

classBaseA{

    publicfunctionecho_a(){

        echo'base_a';

    }

}

classextendsBaseA {

    useTest;

}

$anewA();

$a->echo_a();

输出 'test_a';

二:属性优先级

在 PHP 7.0 之前,在类里定义和 trait 同名的属性,哪怕是完全兼容的也会抛出 E_STRICT(完全兼容的意思:具有相同的访问可见性、初始默认值)。

7.0之后,完全相同的属性,不会抛出错误

<?php

traitTest{

    public$a= 2;

    static$b=1;

}

classA {

    public$a= 2;

    useTest;

}

classB {

    static$b= 1;

    useTest;

}

$anewA();

echo$a->a;

echo"<br>";

echoB::$b;

输出:

image.png

多个trait冲突

使用逗号,可以use 多个trait;

如果use多个方法名相同的trait并且没做任何处理的话,将会产生一个致命错误

<?php

traitTest1{

    publicfunctionecho_a(){

        echo'test1_a';

    }

}

traitTest2{

    publicfunctionecho_a(){

        echo'test2_a';

    }

}

classA  {

    useTest1,Test2;

}

$anewA();

$a->echo_a();

image.png

   解决方法:需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。

<?php

traitTest1{

    publicfunctionecho_a(){

        echo'test1_a';

    }

    publicfunctionecho_b(){

        echo'test1_b';

    }

}

traitTest2{

    publicfunctionecho_a(){

        echo'test2_a';

    }

    publicfunctionecho_b(){

        echo'test2_b';

    }

}

classA  {

    useTest1,Test2{

      Test2::echo_a insteadofTest1;

      Test1::echo_b insteadofTest2;

    }

}

$anewA();

$a->echo_a();

echo"\n";

$a->echo_b();

输出:image.png


as操作符

一:当多个trait冲突,使用insteadof排除其中一个时,可使用as操作符赋予别名进行调用

<?php

traitTest1{

    publicfunctionecho_a(){

        echo'test1_a';

    }

    publicfunctionecho_b(){

        echo'test1_b';

    }

}

traitTest2{

    publicfunctionecho_a(){

        echo'test2_a';

    }

    publicfunctionecho_b(){

        echo'test2_b';

    }

}

classA  {

    useTest1,Test2{

      Test2::echo_a insteadofTest1;

      Test1::echo_b insteadofTest2;

      Test2::echo_b asecho_b_2;//赋予别名

    }

}

$anewA();

$a->echo_a();

echo"\n";

$a->echo_b();

echo"\n";

$a->echo_b_2();

输出:image.png

二:使用as操作符修改访问权限

classA {

    public$a= 1;

 

    useTest{

        Test::echo_a asprivate;

    }

 

    publicfunctionwant_echo_a(){

        $this->echo_a();

    }

}

$anewA();

//$a->echo_a();//直接调用将会报错

$a->want_echo_a();

输出结果:

image.png


Trait 的抽象成员,

<?php

traitTest{

    publicfunction__construct()

    {

        $this->echo_test();

    }

 

    abstractfunctionecho_test();//

}

classA {

    public$a= 2;

    useTest;

    publicfunctionecho_test()

    {

        echo'1';

    }

}

$anewA();

输出:image.png


Trait的静态成员

<?php

traitTest{

    publicfunctionecho_test()

    {

        static$a=1;

        $a++;

        echo$a;

    }

 

}

classA {

    useTest;

}

classB {

    useTest;

}

$anewA();

$bnewB();

$a->echo_test();

echo"\n";

$a->echo_test();

echo"\n";

$b->echo_test();

echo"\n";

$b->echo_test();

输出image.png

静态成员基本和http://www.php20.cn/article/sw/%E9%9D%99%E6%80%81/55 说明一致



以上就是关于trait的说明以及用法了

目录
相关文章
|
5月前
|
PHP 开发者
百度搜索:蓝易云【PHP trait的使用方法】
通过以上方法,我们可以充分利用PHP trait来实现代码复用和组合,提高代码的灵活性和可维护性。
85 3
|
1月前
|
Java API PHP
多多关键字API php java Python
多多关键字API接口广泛应用于商家进行市场分析、竞品分析、关键词优化等场景。商家可以通过分析关键词数据,了解用户需求,制定针对性的营销策略,提高产品的曝光率和转化率。
|
10月前
|
XML JSON 缓存
1688平台按关键字搜索商品接口 代码接口 PHP接口 json格式
1688平台按关键字搜索商品接口 代码接口 PHP接口 json格式
|
编译器 PHP
PHP的关键字是干什么的?一共有哪些?底层原理是什么?
PHP的关键字是干什么的?一共有哪些?底层原理是什么?
108 0
PHP:Trait简单使用
PHP:Trait简单使用
php:类中的static、final、const、parent、self、$this关键字使用方法和区别
php:类中的static、final、const、parent、self、$this关键字使用方法和区别
|
PHP
【PHP】trait详解
【PHP】trait详解
70 0
根据标题关键字生成图片实现优质图片PHP代码
根据标题关键字生成图片实现优质图片PHP代码,用于没有图片的文章,可以用此代码增加文章美观性。