详解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 相关文章推荐
图书管理程序(一)
Oct 09 PHP
php垃圾代码优化操作代码
Aug 05 PHP
色色整理的PHP面试题集锦
Mar 08 PHP
php正则表达式使用的详细介绍
Apr 27 PHP
PHP高级编程实例:编写守护进程
Sep 02 PHP
PHP生成条形图的方法
Dec 10 PHP
php批量删除cookie的简单实现方法
Jan 26 PHP
四种php中webservice实现的简单架构方法及实例
Feb 03 PHP
Yii2中使用join、joinwith多表关联查询
Jun 30 PHP
php 删除指定文件夹的实例讲解
Jul 25 PHP
php微信开发之关注事件
Jun 14 PHP
如何在PHP中使用AES加密算法加密数据
Jun 24 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
快速配置PHPMyAdmin方法
2008/06/05 PHP
php下防止单引号,双引号在接受页面转义的设置方法
2008/09/25 PHP
php下获取客户端ip地址的函数
2010/03/15 PHP
基于session_unset与session_destroy的区别详解
2013/06/03 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
2013/10/26 PHP
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
常用PHP数组排序函数归纳
2016/08/08 PHP
filemanage功能中用到的common.js
2007/04/08 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
window.location的重写及判断location是否被重写
2014/09/04 Javascript
PHP使用方法重载实现动态创建属性的get和set方法
2014/11/17 Javascript
JS获取时间的相关函数及时间戳与时间日期之间的转换
2016/02/04 Javascript
jQuery实现点击水纹波动动画
2016/04/10 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
利用ES6实现单例模式及其应用详解
2017/12/09 Javascript
vue项目引入字体.ttf的方法
2018/09/28 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
小程序实现列表删除功能
2018/10/30 Javascript
[05:26]TI10典藏宝瓶套装外观展示
2020/07/03 DOTA
Python 错误和异常小结
2013/10/09 Python
Python获取央视节目单的实现代码
2015/07/25 Python
Flask框架的学习指南之开发环境搭建
2016/11/20 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
Python实现字典按照value进行排序的方法分析
2017/12/23 Python
Django实现发送邮件功能
2019/07/18 Python
python 多进程共享全局变量之Manager()详解
2019/08/15 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
2021/02/18 Python
python爬虫用request库处理cookie的实例讲解
2021/02/20 Python
用React加CSS3实现微信拆红包动画效果
2017/03/13 HTML / CSS
实例讲解HTML5的meta标签的一些应用
2015/12/08 HTML / CSS
印度最大的酒店品牌网络:OYO Rooms
2016/07/24 全球购物
函授毕业生自我鉴定范文
2014/03/25 职场文书
汽车转让协议书
2015/01/29 职场文书
Python IO文件管理的具体使用
2022/03/20 Python
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏