简单谈谈PHP中的trait
前言
之前的一个同事换工作,在面试被问到了 PHP 的 trait 。因为没用过, 所以没答好,我大概是用过几次的,想了想整理了以下的总结。
trait
trait 是在一些类(Class)的应该具备的特定的属性或方法,而同父级的另外一些类应该避免包含这些属性和方法情况下使用的.
当然, 这也和开发者对类的抽象能力有关, 有些抽象能力好的, 可以减少对 trait 的使用 但是这种情况应该是无法避免的 不然 trait 出现就毫无意义了.
还有一种情况, 就是使用 trait 的时候, 可以起到的约束开发者的作用, 提醒开发者注意需要在开发的过程中调用 trait 的某些属性和方法.
同事则提出了一个好问题, 接口(interface) 不也是这个作用么?
不急, 让我们先看个例子:
比如你要收集网站上各类数据, 开发了 Spider 类. Spider
有个方法叫 request()
负责请求.
<?php namespace XWSoul\Network; class Spider { public function request($url) { //do sth. } }
但是采集数据的过程中, 有些网站对蜘蛛敏感有些则不. 对于敏感的网站, 我们给出了一个使用代理的解决方案. 但是使用代理是会影响抓取速度的. 这就产生了 Spider 的子类有些需要用代理, 而能不用代理则尽量不用的情况.
于是这个时候我们新增了一个 trait Proxy:
<?php namespace XWSoul\Network; trait Proxy { protected $isProxy = false; public function useProxy($proxy) { //do sth proxy setups. $this->isProxy = true; return $this; } public function request($url) { if (!$this->isProxy) { throw new Exception("Please using proxy."); } //do sth. return parent::request($url); } }
trait 重写了 Spider 的 request()
方法, 限定了在没有调用代理的情况下调用会抛出异常.
回到之前的问题, trait 这样的用法和 接口(interface) 有什么区别?
接口的约束是前置的是定义初始就必须实现的, 他可以约束方法的实现却无法约束方法的调用, trait 是一种后置的调用, 他已经实现了方法, 关键的是, 他只对调用了自身的类产生约束(废话一句), 而对没有调用自身的类不产生影响(再一句废话), 同时他是可复用的, 而且没有破坏 Spider 类自身的实现增加, Spider 还是那个 Spider.
我想 trait 的用法再这里已经很有效了吧.
后话
有人可能决定 另外实现一个 request 比如叫, proxyRequst 不就完了么? 你说的好有道理…然是如果我使用了不一样的 代理具体对请求上有细节差异怎么办呢? 在代码里不停的 if if if 么? trait 如此清爽的方案 为何要放弃呢?
总结
好了,以上就是这篇文章的全部内容了希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
相关推荐
-
PHP中trait使用方法详细介绍
说通俗点,PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的. <?php trait Drive { public $carName = 'trait'; public function driving() { echo "driving {$this->carName}\n"; } } class Person { public function eat() { echo "
-
PHP中的Trait 特性及作用
自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits. Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集.Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题. Trait 和一个类相似,但仅仅旨在用细粒度和一致的方式来组合功能.Trait 不能通过它自身来实例化.它为传统继承增加了水平特性的组合:
-
PHP中的traits实现代码复用使用实例
PHP5.4后新增traits实现代码复用机制,Trait和类相似,但不能被实例化,无需继承,只需要在类中使用关键词use引入即可,可引入多个Traits,用','隔开. (1)Trait简单使用 <?php trait A { public $var1 = 'test1'; public function test1() { echo 'trait A::test1()'; } } trait B { public $var2 = 'test2'; public function test2(
-
详解PHP中的Traits
PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法.php的Traits和Go语言的组合功能类似,通过在类中使用use关键字声明要组合的Trait名称,而具体某个Trait的声明使用trait关键词,Trait不能直接实例化.具体用法请看下面的代码: <?php trait Drive { public $carName = 'trait'; public function driving() { echo "driving {$thi
-
php 5.4 全新的代码复用Trait详解
从PHP的5.4.0版本开始,PHP提供了一种全新的代码复用的概念,那就是Trait.Trait其字面意思是"特性"."特点",我们可以理解为,使用Trait关键字,可以为PHP中的类添加新的特性. 熟悉面向对象的都知道,软件开发中常用的代码复用有继承和多态两种方式.在PHP中,只能实现单继承.而Trait则避免了这点.下面通过简单的额例子来进行对比说明. 1. 继承 VS 多态 VS Trait 现在有Publish.php和Answer.php这两个类.要在其中
-
thinkPHP5.0框架引入Traits功能实例分析
本文实例讲述了thinkPHP5.0框架引入Traits功能.分享给大家供大家参考,具体如下: ThinkPHP 5.0开始采用trait功能(PHP5.4+)来作为一种扩展机制,可以方便的实现一个类库的多继承问题. Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集.Traits和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题. 但由于
-
PHP中Trait及其应用详解
从PHP的5.4.0版本开始,PHP提供了一种全新的代码复用的概念,那就是Trait.Trait其字面意思是"特性"."特点",我们可以理解为,使用Trait关键字,可以为PHP中的类添加新的特性. 熟悉面向对象的都知道,软件开发中常用的代码复用有继承和多态两种方式.在PHP中,只能实现单继承.而Trait则避免了这点.下面通过简单的额例子来进行对比说明. 1. 继承 VS 多态 VS Trait 现在有Publish.php和Answer.php这两个类.要在其中
-
PHP中的traits简单使用实例
PHP 5.4中的traits,是新引入的特性,中文还真不知道如何准确翻译好.其实际的目的,是为了有的场合想用多继承,但PHP又没多继承,于是就发明了这样的一个东西. Traits可以理解为一组能被不同的类都能调用到的方法集合,但Traits不是类!不能被实例化.先来例子看下语法: <?php trait myTrait{ function traitMethod1(){} function traitMethod2(){} } //然后是调用这个traits,语法为: class
-
PHP 实现代码复用的一个方法 traits新特性
在阅读yii2源码的时候接触到了trait,就学习了一下,写下博客记录一下. 自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits. Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集.Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题. Trait 和一个类相似,但仅仅旨在用细粒度和一致的方式来组
-
简单谈谈PHP中的trait
前言 之前的一个同事换工作,在面试被问到了 PHP 的 trait .因为没用过, 所以没答好,我大概是用过几次的,想了想整理了以下的总结. trait trait 是在一些类(Class)的应该具备的特定的属性或方法,而同父级的另外一些类应该避免包含这些属性和方法情况下使用的. 当然, 这也和开发者对类的抽象能力有关, 有些抽象能力好的, 可以减少对 trait 的使用 但是这种情况应该是无法避免的 不然 trait 出现就毫无意义了. 还有一种情况, 就是使用 trait 的时候, 可以起到
-
简单谈谈React中的路由系统
React中的路由系统 提起路由,首先想到的就是 ASPNET MVC 里面的路由系统--通过事先定义一组路由规则,程序运行时就能自动根据我们输入的URL来返回相对应的页面.前端中的路由与之类似,前端中的路由是根据你定义的路由规则来渲染不同的页面/组件,同时也会更新地址栏的URL.本篇文章要介绍的是React中经常使用到的路由,react-router主要使用HTML5的history API来同步你的UI和URL. react-router的最新版本是v4.1.1,由于4.0版本和之间的版本A
-
简单谈谈JS中的正则表达式
1.正则表达式包括两部分 ①定义正则表达式的规则: ②正则表达式的模式(i/g/m): 2.声明正则表达式 ① 字面量声明: var reg = /表达式规则/表达式模式: eg:var reg = /white/g: ② 使用new关键字: var reg = new RegExp("表达式规则","表达式模式") eg: var reg = new RegExp("white","g"): 3.正则表达式的三种模式 ① g
-
简单谈谈Python中的json与pickle
这是用于序列化的两个模块: • json: 用于字符串和python数据类型间进行转换 • pickle: 用于python特有的类型和python的数据类型间进行转换 Json 模块提供了四个功能:dumps.dump.loads.load pickle 模块提供了四个功能:dumps.dump.loads.load import pickle data = {'k1':123, 'k2':888} #dumps可以将数据类型转换成只有python才认识的字符串 p_str = pickle.
-
简单谈谈python中的语句和语法
python程序结构 python"一切皆对象",这是接触python听到最多的总结了.在python中最基层的单位应该就是对象了,对象需要靠表达式建立处理,而表达式往往存在于语句中,多条语句组成代码块,多个代码块再组成一整个程序.python的核心其实是由语句和表达式组成.所以在这里简单探讨一下python中的语句和表达式. 因为以后可能会接触到两个版本的python,所以这里讲一讲python2与python3的语句差异: 1.python2中没有nolocal语句. 2.prin
-
简单谈谈axios中的get,post方法
学习vue和nodejs的过程当中,涉及到了axios,今天为了测试,写了get和post两个方法来跟node服务端交互,结果因为header和参数弄了好久,在此记录一下,同时分享: 由于刚接触axios,在测试方法中,写的都是很简单的东西,不过能够实现基础功能,大神看到的话..非常欢迎指导.. //GET方法 axios.get(url, { params: { 'key': 'value' } }).then(function (response) { alert(''.concat(res
-
简单谈谈Java中的方法和方法重载
今天我们就讲一点内容,来说说Java中的方法和方法重载以及需要注意的一些地方: 方法: Java的方法类似与其他语言的函数,是一段用来完成特定功能的代码片段, 声明格式: [修饰符1 修饰符2 ....] ,返回值类型 方法名 (形式参数列表) { Java语句: - - -} 形式参数:在方法被调用时用于接受外界输入的数据: 实参: 调用方法时世界传给方法的数据: 返回值: 方法在执行完毕后返回给调用他的环境的数据: 返回值类型: 事先约定好的返回值的数据类型,如无返回值必须给出返回值类型vo
-
简单谈谈MySQL中的int(m)
我们在设计表的时候,如果碰到需要设置int(整型)的时候,通常会按照惯例(大家都这样写)设置成int(11).那么这里为什么是11呢?代表的又是什么呢? 以前我一直以为这里是在限制int显示的宽度,后来仔细研究和通过上网查询发现,事实并不是那样的. 确切的来说,这里的"宽度"只是一个"预期值",它所代表的仅仅是你在设计数据表结构时,想让该列日后显示的值宽度为多少,但是具体存入值的宽度多少不会受任何影响. 当然,它的作用不仅如此,在存入数据的时候,还是有一定区别的,这
-
简单谈谈python中的lambda表达式
最近在coding时发现使用lambda还是有诸多优点的,很多时候代码更整洁,更pythonic,所以在此简单总结一下 1.lambda是什么 举个简单的例子: func = lambda x: x*x def func(x): return x*x 两个func的定义是完全相同的,那两种函数定义方法配合map使用,将list中所有元素求平方,代码会是什么样的, def func(x): return x*x map(func, [i for i in range(10)]) map(lambd
-
简单谈谈PHP中的Reload操作
前言 有很多前辈告诫过我们,reload 能保证整个过程的平滑性,所谓平滑性指的是在 reload 的过程中,旧的进程在处理完当前请求前不会提前终止.很多年来,我从来没有质疑过这种说法,直到有一天,当我 reload 的时候,出现了 502 错误,让我不得不重新思考. 如何重现问题呢?让我们写一个简单的脚本来模拟: <?php sleep(11); echo "foo"; ?> 此时用浏览器浏览这个网址,接着立刻执行 reload 操作,就能看到 502 错误了. 难道 P
随机推荐
- 详细解析Ruby中的变量
- 详解angularJS自定义指令间的相互交互
- 用“本地安全策略”保护系统安全
- Java设计模式之工厂模式(Factory模式)介绍
- PHP图片等比例缩放生成缩略图函数分享
- python复制与引用用法分析
- c#在控制台输出彩色文字的方法
- Mysql数据库增量备份的思路和方法
- 页面图片浮动左右滑动效果的简单实现案例
- lnmp关闭mysql日志保护硬盘空间的方法
- JS模拟的Map类实现方法
- 详解XMLHttpRequest(一)同步请求和异步请求
- 解决Eclipse配置Tomcat出现Cannot create a server using the selected type错误
- Android中Activity的生命周期探讨
- Android Zxing二维码扫描图片拉伸的解决方法
- C#中Socket通信用法实例详解
- php中运用http调用的GET和POST方法示例
- 思科MDS与McDATA存储局域网交换机并肩战斗
- jQuery实现checkbox即点即改批量删除及中间遇到的坑
- C语言合并两个带头节点升序排列链表