详解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读注册表
Oct 09 PHP
php session_start()关于Cannot send session cache limiter - headers already sent错误解决方法
Nov 27 PHP
php header示例代码(推荐)
Sep 08 PHP
比较详细PHP生成静态页面教程
Jan 10 PHP
TMDPHP 模板引擎使用教程
Mar 13 PHP
PHP运行环境配置与开发环境的配置(图文教程)
Jun 04 PHP
解析PHP多种序列化与反序列化的方法
Jun 06 PHP
yii操作cookie实例简介
Jul 09 PHP
php判断类是否存在函数class_exists用法分析
Nov 14 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
Jul 03 PHP
php获取用户真实IP和防刷机制的实例代码
Nov 28 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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中mysql连接和基本操作代码(快速测试使用,简单方便)
2014/04/25 PHP
Chrome Web App开发小结
2014/09/04 PHP
Zend Framework自定义Helper类相关注意事项总结
2016/03/14 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
GWT中复制到剪贴板 js+flash实现复制 兼容性比较好
2010/03/07 Javascript
TimergliderJS 一个基于jQuery的时间轴插件
2011/12/07 Javascript
巧方法 JavaScript获取超链接的绝对URL地址
2016/06/14 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
浅谈javascript中执行环境(作用域)与作用域链
2016/12/08 Javascript
JavaScript实现定时页面跳转功能示例
2017/02/14 Javascript
JavaScript Base64 作为文件上传的实例代码解析
2017/02/14 Javascript
基于React实现表单数据的添加和删除详解
2017/03/14 Javascript
9种方法优化jQuery代码详解
2020/02/04 jQuery
微信小程序实现页面左右滑动
2020/11/16 Javascript
addEventListener()和removeEventListener()追加事件和删除追加事件
2020/12/04 Javascript
python 实现归并排序算法
2012/06/05 Python
python使用win32com在百度空间插入html元素示例
2014/02/20 Python
sqlalchemy对象转dict的示例
2014/04/22 Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
Python实现批量下载图片的方法
2015/07/08 Python
Django框架中render_to_response()函数的使用方法
2015/07/16 Python
使用tkinter实现三子棋游戏
2021/02/25 Python
html5实现微信打飞机游戏
2014/03/27 HTML / CSS
AmazeUI 单选框和多选框的实现示例
2020/08/18 HTML / CSS
写自荐信三大法宝
2014/01/24 职场文书
语文教学随笔感言
2014/02/18 职场文书
教师对学生的评语
2014/04/28 职场文书
防灾减灾活动总结
2014/08/30 职场文书
2014年预备党员端正入党动机思想汇报
2014/09/13 职场文书
公司离职证明标准格式
2014/11/18 职场文书
2014年基层党支部工作总结
2014/12/04 职场文书
丽江古城导游词
2015/02/03 职场文书
拾金不昧表扬稿大全
2015/05/05 职场文书
优秀大学生申请书
2019/06/24 职场文书
golang 如何用反射reflect操作结构体
2021/04/28 Golang
Python pyecharts案例超市4年数据可视化分析
2022/08/14 Python