详解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 地址栏信息的获取代码
Jan 07 PHP
php过滤XSS攻击的函数
Nov 12 PHP
php获取文件内容最后一行示例
Jan 09 PHP
js和php邮箱地址验证的实现方法
Jan 09 PHP
PHP date()函数警告: It is not safe to rely on the system解决方法
Aug 20 PHP
字符串长度函数strlen和mb_strlen的区别示例介绍
Sep 09 PHP
php过滤html标记属性类用法实例
Sep 23 PHP
php基于mcrypt的加密解密实例
Oct 27 PHP
Symfony数据校验方法实例分析
Jan 26 PHP
Windows Server 2008 R2和2012中PHP连接MySQL过慢的解决方法
Jul 02 PHP
PHP线程的内存回收问题
Jul 08 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
Apr 21 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将DateTime对象转化为友好时间显示的实现代码
2011/09/20 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
jqgrid 编辑添加功能详细解析
2013/11/08 Javascript
jQuery打印图片pdf、txt示例代码
2014/07/22 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
2015/12/02 Javascript
EasyUI在表单提交之前进行验证的实例代码
2016/06/24 Javascript
微信小程序 网络API Websocket详解
2016/11/09 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
2017/01/22 Javascript
AngulaJS路由 ui-router 传参实例
2017/04/28 Javascript
Vue中组件之间数据的传递的示例代码
2017/09/08 Javascript
解析Json字符串的三种方法日常常用
2018/05/02 Javascript
js canvas实现写字动画效果
2018/11/30 Javascript
JS实现的图片选择顺序切换和循环切换功能示例【测试可用】
2018/12/28 Javascript
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
2020/05/06 Javascript
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
[02:50]【扭转乾坤,只此一招】DOTA2全新版本永雾林渊开启新篇章
2020/12/24 DOTA
Python获取文件ssdeep值的方法
2014/10/05 Python
Python新手入门最容易犯的错误总结
2017/04/24 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
如何优雅地处理Django中的favicon.ico图标详解
2018/07/05 Python
python实现简单tftp(基于udp协议)
2018/07/30 Python
对pandas中时间窗函数rolling的使用详解
2018/11/28 Python
python实现的生成word文档功能示例
2019/08/23 Python
pycharm运行scrapy过程图解
2019/11/22 Python
python正则表达式实例代码
2020/03/03 Python
python飞机大战游戏实例讲解
2020/12/04 Python
纯css实现照片墙3D效果的示例代码
2017/11/13 HTML / CSS
网页中的电话号码如何实现一键直呼效果_附示例
2016/03/15 HTML / CSS
PHP两种查询函数array/row的区别
2013/06/03 面试题
建筑结构施工专业推荐信
2014/02/21 职场文书
和谐家庭演讲稿
2014/05/24 职场文书
2014年党支部承诺书
2014/05/30 职场文书
2016大学生党校学习心得体会
2016/01/06 职场文书
vue3引入highlight.js进行代码高亮的方法实例
2022/04/08 Vue.js