详解PHP神奇又有用的Trait


Posted in PHP onMarch 25, 2019

php和java,c++一样都是单继承模式。但是像python,是支持多继承(即Mixin模式)。那么如何在php中实现多继承模式?这就需要使用trait。

trait Arrayabletrait{
	public function toArray(){

	}
}

class Model{
	use Arrayabletrait;
}


$model = new Model();
$model->toArray();

Trait使用场景

  1. 有些功能不需要类的方法属性,但是在不同的类都有使用需求。例如上面的对象转数组方法。这种情况可以使用一个基类定义toArray方法,则需要将这类基础方法定义在尽可能顶层的基类当中,保证所有的类都能够调用这个方法。
  2. 类因为某些需求,已经继承了第三方类对象。例如第三方orm模型类。这种情况如果要给类附加一些公共的功能,除了创建一个继承于orm模型的基类,复制一套公共功能的代码之外,就可以使用trait。

trait使用注意

方法优先级

trait Arrayabletrait{

	public function logname(){
		return 'trait:'.$this->name;
	}

	public static function staticlog(){
		return 'trait:'.self::$staticname;
	}
}
class Obj{
	protected $name = 'Obj';
	public static $staticname = 'Obj';
	public function logname(){
		return 'obj:'.$this->name;
	}
}
class Model extends Obj{
	protected $name = 'model';
	public static $staticname = 'model';
	use Arrayabletrait;

	public function logname(){
		return 'model:'.$this->name;
	}
	public static function staticlog(){
		return 'model:'.self::$staticname;
	}
}

class Model2 extends Obj{
	protected $name = 'model2';
	public static $staticname = 'Model2';
	use Arrayabletrait;
}

$model = new Model();
$model2 = new Model2();
echo $model->logname()."\n";
echo $model2->logname()."\n";
echo Model::staticlog()."\n";
echo Model2::staticlog()."\n";

上面输出内容分别为model:model,trait:model2,model:model,trait:model2.可以看出,trait方法优先级为 当前对象>trait>父类,以上规则同样使用于静态调用。

属性定义要特别小心!!trait中可以定义属性。但是不能和usetrait当前类定义的属性相同,否则会报错:define the same property。但是,如果父类使用了trait,子类定义trait中存在的属性,则没有问题。

trait Arrayabletrait{
	public $logger='file';
	public function log(){
		return 'trait:'.$this->logger.$this->name;
	}
}
class Obj{
	use Arrayabletrait;
	protected $name = 'Obj';

}
class Model extends Obj{
	protected $logger = 'redis';
}
$model = new Model();
echo $model->log()."\n";

私有属性私有方法。triat中可以方位use类的私有属性私有方法!!

从以上可以看出,trait本身是对类的一个扩展,在trait中使用$this ,self,static,parent都与当前类一样,zend底层将trait代码嵌入到类当中,相当于底层帮我们实现了代码复制功能。

多个trait相同方法。

trait Arrayabletrait1{
	public function log(){
		return 'trait1:'.$this->logger.$this->name;
	}
	public function logname(){
		return 'trait1:'.$this->name;
	}
}
trait Arrayabletrait2{
	public function log(){
		return 'trait2:'.$this->logger.$this->name;
	}
	public function logname(){
		return 'trait1:'.$this->name;
	}
}

class Model{
	public $name = 'model';
	use Arrayabletrait1,Arrayabletrait2{
		Arrayabletrait1::log insteadof Arrayabletrait2;
		Arrayabletrait2::logname insteadof Arrayabletrait1;
		Arrayabletrait2::logname as logname1;
	}
	protected $logger = 'redis';
}
$model = new Model();
echo $model->log()."\n";
echo $model->logname1()."\n";

多trait相同的方法,需要使用instanceof 指定使用哪个trait的方法。instanceof后面的使用的trait。可以使用as设置添加方法别名(添加,原有方法还是能调用!!)。as还可以改变方法的访问控制

Arrayabletrait2::logname as private改为私有方法。

以上所述是小编给大家介绍的PHP神奇又有用的Trait详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
一篇不错的PHP基础学习笔记
Mar 18 PHP
PHP显示今天、今月、上月、今年的起点/终点时间戳的代码
May 25 PHP
thinkPHP的Html模板标签使用方法
Nov 13 PHP
php实现MD5加密16位(不要默认的32位)
Aug 12 PHP
ThinkPHP3.1新特性之对分组支持的改进与完善概述
Jun 19 PHP
php基于表单密码验证与HTTP验证用法实例
Jan 06 PHP
php中实现可以返回多个值的函数实例
Mar 21 PHP
PHP后端银联支付及退款实例代码
Jun 23 PHP
PHP观察者模式实例分析【对比JS观察者模式】
May 22 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
Oct 11 PHP
PHP读取文件,解决中文乱码UTF-8的方法分析
Jan 22 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
Feb 27 PHP
PHP自动载入类文件函数__autoload的使用方法
Mar 25 #PHP
PHP生成短网址的思路以及实现方法的详解
Mar 25 #PHP
PHP错误提示It is not safe to rely on the system……的解决方法
Mar 25 #PHP
mongodb和php的用法详解
Mar 25 #PHP
PHP随机数函数rand()与mt_rand()的讲解
Mar 25 #PHP
php微信扫码支付 php公众号支付
Mar 24 #PHP
PHP实现支持CURL字符串证书传输的方法
Mar 23 #PHP
You might like
php mssql 时间格式问题
2009/01/13 PHP
DISCUZ在win2003环境下 Unable to access ./include/common.inc.php in... 的问题终极解决方案
2011/11/21 PHP
php多次include后导致全局变量global失效的解决方法
2015/02/28 PHP
ThinkPHP的常用配置选项汇总
2016/03/24 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
select标记美化--JS式插件、后期加载
2013/04/01 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
JS学习之表格的排序简单实例
2016/05/16 Javascript
Angularjs修改密码的实例代码
2017/05/26 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
JS实现可视化音频效果的实例代码
2020/01/16 Javascript
JavaScript 引用类型实例详解【数组、对象、严格模式等】
2020/05/13 Javascript
vue实现学生信息管理系统
2020/05/30 Javascript
JS实现多选框的操作
2020/06/24 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
jQuery实现动态加载瀑布流
2020/09/01 jQuery
[42:56]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
详解Python中break语句的用法
2015/05/14 Python
Python实现登录接口的示例代码
2017/07/21 Python
Python中类的初始化特殊方法
2017/12/01 Python
Numpy截取指定范围内的数据方法
2018/11/14 Python
python面试题Python2.x和Python3.x的区别
2019/05/28 Python
Python实现K折交叉验证法的方法步骤
2019/07/11 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
tensorflow 报错unitialized value的解决方法
2020/02/06 Python
keras 如何保存最佳的训练模型
2020/05/25 Python
部署Django到阿里云服务器教程示例
2020/06/03 Python
css3实现画半圆弧线的示例代码
2017/11/06 HTML / CSS
移动web模拟客户端实现多方框输入密码效果【附代码】
2016/03/25 HTML / CSS
日本高岛屋百货购物网站:TAKASHIMAYA
2019/03/24 全球购物
副主任竞聘演讲稿
2014/08/18 职场文书
未婚证明格式
2015/06/15 职场文书
MySQL 如何设计统计数据表
2021/06/15 MySQL
Windows server 2012 NTP时间同步的实现
2022/06/25 Servers