详解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 相关文章推荐
不用数据库的多用户文件自由上传投票系统(1)
Oct 09 PHP
新手学PHP之数据库操作详解及乱码解决!
Jan 02 PHP
PHP extract 将数组拆分成多个变量的函数
Jun 30 PHP
apache mysql php 源码编译使用方法
May 03 PHP
基于PHP读取csv文件内容的详解
Jun 18 PHP
php结合ajax实现赞、顶、踩功能实例
May 12 PHP
PHP获取POST数据的几种方法汇总
Mar 03 PHP
PHP 将dataurl转成图片image方法总结
Oct 14 PHP
PHP异常处理定义与使用方法分析
Jul 25 PHP
Laravel中前端js上传图片到七牛云的示例代码
Sep 04 PHP
php服务器的系统详解
Oct 12 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
Nov 26 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
关于手调机和数调机的选择
2021/03/02 无线电
第1次亲密接触PHP5(2)
2006/10/09 PHP
php使用curl打开https网站的方法
2015/06/17 PHP
如何使用微信公众平台开发模式实现多客服
2016/01/06 PHP
Nigma vs Alliance BO5 第一场2.14
2021/03/10 DOTA
JavaScript中也使用$美元符号来代替document.getElementById
2010/06/19 Javascript
原生javaScript做得动态表格(注释写的很清楚)
2013/12/29 Javascript
javascript正则表达式中的replace方法详解
2015/04/20 Javascript
如何在Linux上安装Node.js
2016/04/01 Javascript
js操作浏览器的参数方法
2017/01/21 Javascript
原生JS+Canvas实现五子棋游戏实例
2017/06/19 Javascript
vue-cli+webpack项目 修改项目名称的方法
2018/02/28 Javascript
JS中的回调函数实例浅析
2018/03/21 Javascript
js jquery 获取某一元素到浏览器顶端的距离实现方法
2018/09/05 jQuery
vue template中slot-scope/scope的使用方法
2018/09/06 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
扫微信小程序码实现网站登陆实现解析
2019/08/20 Javascript
JavaScript This指向问题详解
2019/11/25 Javascript
[07:20]2014DOTA2西雅图国际邀请赛 选手讲解积分赛第二天
2014/07/11 DOTA
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
[01:04]DOTA2:伟大的Roshan雕塑震撼来临
2015/01/30 DOTA
python图像处理入门(一)
2019/04/04 Python
pytorch使用指定GPU训练的实例
2019/08/19 Python
python3获取文件中url内容并下载代码实例
2019/12/27 Python
基于Python实现粒子滤波效果
2020/12/01 Python
解释一下Windows的消息机制
2014/01/30 面试题
制药工程专业应届生求职信
2013/09/24 职场文书
应届生会计求职信
2013/11/11 职场文书
学校庆元旦歌咏比赛主持词
2014/03/18 职场文书
保护动物的标语
2014/06/11 职场文书
自我推荐信怎么写
2015/03/24 职场文书
2015年语文教研组工作总结
2015/05/23 职场文书
2016年清明节期间群众祭祀活动工作总结
2016/04/01 职场文书
完美处理python与anaconda环境变量的冲突问题
2021/04/07 Python
Python使用socket去实现TCP客户端和TCP服务端
2022/04/12 Python
详解Go语言中配置文件使用与日志配置
2022/06/01 Golang