当前位置:首页 > PHP教程 > 正文内容

PHP中Trait的用法及示例_php教程,trait

搜教程4年前 (2020-01-30)PHP教程134

php实现微信企业付款到零钱_php教程

微信支付企业付款到零钱功能应用广泛,比如微信红包奖励、业务结算等。通过企业向个人付款,付款资金将直接进入个人用户微信零钱中。

PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法,为了解决这个问题,php出了Trait这个特性。(Traits和Go语言的组合功能有点类似)

用法:通过在类中使用use关键字声明要组合的Trait名称,而具体某个Trait的声明使用trait关键词,Trait不能直接实例化。

<?php
trait Drive {
    public $carName = 'BMW';
    public function driving() {
        echo "driving {$this->carName}\n";
    }
}
 
class Person {
    public function age() {
        echo "i am 18 years old\n";
    }
}
 
class Student extends Person {
    use Drive;
    public function study() {
        echo "Learn to drive \n";
    }
}
 
$student = new Student();
$student->study();  //输出:Learn to drive 
$student->age();    //输出:i am 18 years old
$student->driving();//输出:driving BMW

结论:

Student类通过继承Person,有了age方法

通过组合Drive,有了driving方法和属性carName。

如果Trait、基类和本类中都存在某个同名的属性或者方法,最终会保留哪一个呢?通过下面的代码测试一下:

<?php
 
trait Drive {
    public function hello() {
        echo "hello 周伯通\n";
    }
    public function driving() {
        echo "周伯通不会开车\n";
    }
}
 
class Person {
    public function hello() {
        echo "hello 大家好\n";
    }
    public function driving() {
        echo "大家都会开车\n";
    }
}
 
class Student extends Person {
    use Drive;//trait 的方法覆盖了基类Person中的方法,所以Person中的hello 和driving被覆盖
    public function hello() {
        echo "hello 新学员\n";//当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,所以此处hello会覆盖trait中的
        hello
    }
}
 
$student = new Student();
$student->hello();    //输出:hello 新学员
$student->driving();  //输出:周伯通不会开车

结论:当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,而 trait 的方法又覆盖了基类中的方法。

深入理解PHP中七个预定义接口_php教程

该接口不能被类直接实现,如果直接写了一个普通类实现了该遍历接口,是会直接报致命的错误,提示使用 Iterator(迭代器接口)或者 IteratorAggregate(聚合迭代器接口)来实现,这两个接口后面会介绍;所有通常情况下......

如果要组合多个Trait,通过逗号分隔 Trait名称:

use Trait1, Trait2;

如果多个Trait中包含同名方法或者属性时,会怎样呢?答案是当组合的多个Trait包含同名属性或者方法时,需要明确声明解决冲突,否则会产生一个致命错误。

<?php
trait Trait1 {
    public function hello() {
        echo "Trait1::hello\n";
    }
    public function hi() {
        echo "Trait1::hi\n";
    }
}
 
trait Trait2 {
    public function hello() {
        echo "Trait2::hello\n";
    }
    public function hi() {
        echo "Trait2::hi\n";
    }
}
 
class Class1 { 
    use Trait1, Trait2;
}
 
//输出:Fatal error:  Trait method hello has not been applied, because there are collisions with other trait
 methods on Class1 in

使用insteadof和as操作符来解决冲突,insteadof是使用某个方法替代另一个,而as是给方法取一个别名,具体用法请看代码:

<?php
trait Trait1 {
    public function hello() {
        echo "Trait1::hello \n";
    }
    public function hi() {
        echo "Trait1::hi \n";
    }
}
trait Trait2 {
    public function hello() {
        echo "Trait2::hello\n";
    }
    public function hi() {
        echo "Trait2::hi\n";
    }
}
class Class1 {
    use Trait1, Trait2 {
        Trait2::hello insteadof Trait1;
        Trait1::hi insteadof Trait2;
    }
}
 
class Class2 {
    use Trait1, Trait2 {
        Trait2::hello insteadof Trait1;
        Trait1::hi insteadof Trait2;
        Trait2::hi as hei;
        Trait1::hello as hehe;
    }
}
 
$Obj1 = new Class1();
$Obj1->hello();
$Obj1->hi();
echo "\n";
$Obj2 = new Class2();
$Obj2->hello();
$Obj2->hi();
$Obj2->hei();
$Obj2->hehe();

输出

Trait2::hello
Trait1::hi 
 
Trait2::hello
Trait1::hi 
Trait2::hi
Trait1::hello
<?php
trait Hello {
    public function hello() {
        echo "hello,我是周伯通\n";
    }
}
class Class1 {
    use Hello {
        hello as protected;
    }
}
class Class2 {
    use Hello {
        Hello::hello as private hi;
    }
}
$Obj1 = new Class1();
$Obj1->hello(); # 报致命错误,因为hello方法被修改成受保护的
 
$Obj2 = new Class2();
$Obj2->hello(); # 输出: hello,我是周伯通,因为原来的hello方法仍然是公共的
$Obj2->hi();  # 报致命错误,因为别名hi方法被修改成私有的
Uncaught Error: Call to protected method Class1::hello() from context '' in D:\web\mytest\p.php:18

Trait 也能组合Trait,Trait中支持抽象方法、静态属性及静态方法,测试代码如下:

<?php
trait Hello {
    public function sayHello() {
        echo "Hello 我是周伯通\n";
    }
}
 
trait World {
    use Hello;
    public function sayWorld() {
        echo "hello world\n";
    }
    abstract public function getWorld();
    public function inc() {
        static $c = 0;
        $c = $c + 1;
        echo "$c\n";
    }
    public static function doSomething() {
        echo "Doing something\n";
    }
}
 
class HelloWorld {
    use World;
    public function getWorld() {
        return 'do you get World ?';
    }
}
 
$Obj = new HelloWorld();
$Obj->sayHello();
$Obj->sayWorld();
echo $Obj->getWorld() . "\n";
HelloWorld::doSomething();
$Obj->inc();
$Obj->inc();

输出

Hello 我是周伯通
hello world
do you get World ?
Doing something12

以上就是PHP中Trait的用法及示例的详细内容,更多请关注ki4网其它相关文章!

关于PHP框架中.env文件的加载过程_php教程

现在很多框架使用根目录的.env文件来配置环境变量,php本身是不会去解析这个文件的,需要使用php代码读取和解析这个文件放入环境变量中.......

扫描二维码推送至手机访问。

版权声明:本文由搜教程网发布,如需转载请注明出处。

本文链接:https://www.sojiaocheng.cn/17072.html

标签: trait
分享给朋友:

“PHP中Trait的用法及示例_php教程,trait” 的相关文章

怎样运用PHP生成随机字符串【php教程】,PHP生成随机字符串

怎样运用PHP生成随机字符串【php教程】,PHP生成随机字符串

运用PHP生成随机,唯一,字母数字字符串。 例子: EA070 aBX32gTf 要领1: 第一种要领是最轻易明白的要领。它能够完成以下: -将一切能够的字母存储到字符串中。 -生成从0到字符串长度-1的随机索引。 -打印该索引处的字母。 -实行此步骤n次(个中n是所需字符串...

PHP数据类型及数据类型检测的引见【php教程】,PHP

PHP数据类型及数据类型检测的引见【php教程】,PHP

本篇文章给人人带来的内容是关于PHP数据范例及数据范例检测的引见,有肯定的参考价值,有须要的朋侪能够参考一下,愿望对你有所协助。 数据范例 数据范例分为三种:标量型、复合型、特别范例标量型: boolean(布尔型) integer(整型)float(浮点型) string(字符串型)...

PHP如何将excel文件导入mysql数据库?【php教程】,PHP,excel导入mysql数据库

PHP如何将excel文件导入mysql数据库?【php教程】,PHP,excel导入mysql数据库

在这篇文章中,我将给人人引见怎样运用PHP将excel文件导入mysql数据库。有时候我们须要从治理面板增加数据,如产物,项目,用户,电子邮件等。假如我们的数据很少,那末手工增加就能够了,然则假如我们的excel文件或许csv文件的数据比较多,那末存储数据的时候就比较长,这时候我们就须要直接导入xl...

php中assert和eval的细致引见(代码示例)【php教程】,php

本篇文章给人人带来的内容是关于php中assert和eval的细致引见(代码示例),有肯定的参考价值,有须要的朋侪能够参考一下,愿望对你有所协助。 assert 推断一个表达式是不是建立。返回true or false; <?php $s = 123; assert("is_int($s)...

PHP顺序运转机能剖析(图文)【php教程】,PHP

PHP顺序运转机能剖析(图文)【php教程】,PHP

本篇文章给人人带来的内容是关于PHP顺序运转机能剖析(图文),有肯定的参考价值,有须要的朋侪能够参考一下,愿望对你有所协助。 php在使用了xdebug后,能够设置xdebug相干的设置,生成运转的日记。 在php.ini中设置: xdebug.profiler_enable = 1...

PHP疾速排序算法完成的道理及代码引见【php教程】,php,算法,排序,快速排序

PHP疾速排序算法完成的道理及代码引见【php教程】,php,算法,排序,快速排序

本篇文章给人人带来的内容是关于PHP疾速排序算法完成的道理及代码引见,有肯定的参考价值,有须要的朋侪能够参考一下,愿望对你有所协助。 算法道理 以下动图来自五分钟学算法,演示了疾速排序算法的道理和步骤。 步骤: 从数组中选个基准值 将数组中大于基准值的放同一边、小于基准值的放另...