Trait

Trait 是一种类似PHP单继承语言而准备的代码复用机制

目前可在很多框架汇总看到,比如Yii 、Laravel

为什么要用到这个?
php是单继承的语言,而Trait就是为了解决php不能多继承提高代码的复用并且摒弃一下多线程的诟病而产生的。

1.确定版本:

使用的是在线调试工具
限制:php5.4开始可以使用

http://www.shucunwang.com/RunCode/php5.4/
图片1
我们选择5.4的版本

ps:当然选择低版本会报错误
syntax error, unexpected T_STRING

2.先简单实现Trait

a)创建
图片2
ps:Trait不能被实例化
b)调用
图片3打印结果:图片4

当要调用多个的时候
图片5打印结果:图片6

3.优先级(如果类中方法与trait中重名,那么用的是谁的?)

图片7运行结果:图片8

总结:
a)Trait会覆盖当前类继承的方法
b)当前类的方法会覆盖Trait的方法
即:调用类>Trait>父类

4.多个Trait冲突问题(ps:当多个Trait中方法名相同时怎么处理?)

如果直接使用,会产生致命错误
因此需要这样解决
图片9运行结果:图片10

由此看出
a)这里声明Test中的testA方法替换Test1中的TestA方法
b)Test1中的testA方法起别名为bb
总结:
当出现冲突时可以使用insteadof来确定使用哪一个方法
使用as就可以使用另一个方法

相关测试

a)直接其别名是别名不使用insteadof声明是否可以? (否,会报错)
b)别名可以单独使用? (可以)
c)当出现三个或三个以上时怎样处理?
图片11运行结果:图片12
ps:少一个依旧会报错

5.Trait嵌套(Trait中包含Trait)
图片13运行结果:图片14
总结:
依旧使用use可以实现相互嵌套

相关测试
a)如果冲突是否和类中解决一样? 是的,不处理会报错
b)Trait中的方法与嵌套中的方法吗一样,那么是冲突还是按优先级分?
图片15运行结果:图片16
可见是按当前的算。

6.Trait支持抽象方法、支持静态方法,不可以直接定义静态变量,但静态变量可以被Trait方法引用
图片17运行结果:图片18

ps:当定义抽象方法时,必须在使用它的class中实现,否则会产生致命错误.
当然Trait中也可以定义属性。不过如果类中定义了和他不同的属性也会报致命错误。

从上面可以看出,Trait既不是接口也不是类。主要是为了解决单继承语言的限制。是PHP多重继承的一直解决方案。
比如同时要继承两个Abstract Class将会很麻烦,而Trait就是为了解决类似问题。它能被加入到一个或多个已存在的类中。它声明了类能做什么(表面了其接口的特性),同时也包含具体的实现(表面了其类的特性)

总的来说,个人感觉就是Trait = abstract class - interface

bigpipe技术初探

情景模拟:
当网页越来越大,相应的请求数据,css,js等也越来越多,页面的加载速度就变的越来越慢慢,通过研究数据表明,用户能够容忍的大概为2.5s,如果达到3到4s还是白页的话,那么用户基本也就失去耐心。

目前我们的处理方法基本基于ajax来减少加载时间。

页面完整加载流程如下:
1) 用户访问网页,浏览器发送一个HTTP 请求到网络服务器
2) 服务器解析这个请求,然后从存储层去数据,接着生成一个html 文件内容,并在一个HTTP Response 中把它传送给客户端
3) HTTP response 在网络中传输
4) 浏览器解析这个Response ,创建一个DOM 树,然后下载所需的CSS 和JS文件
5) 下载完CSS 文件后,浏览器解析他们并且应用在相应的内容上
6) 下载完JS 后,浏览器解析和执行他们

可以看出,这些都是按照严格的顺序来执行的,当其中有一个操作没有执行结束,后面的操作就不会之执行,即操作之间不能重叠。这样就易造成性能的瓶颈。(这样就造成性能的瓶颈:服务器生成一个页面的内容时,浏览器是空闲的,显示空白内容;而当浏览器加载渲染页面内容时,服务器又是空闲的,时间与性能的浪费由此产生。)

解决方案:

bigpipe 是有Facebook发明的一种页面加载技术,即一种减少http请求的,首屏快速加载的异步加载页面方案;其核心思想是并行,服务器生成的数据和浏览器渲染数据的并行。

php实现原理:利用ob_flush()与flush()将缓冲区的内容提前输出,浏览器可提早加载这部分的内容,无需等待所有输出完成再加载。将页面内容划分为一个个小块,输出一个后在输出下一个,使用户尽早看到页面内容,优化用户体验。

详细内容:
bigPipe提出分块的概念,即根据页面内容位置的不同,将整个页面分成不同的块儿– 称为pagelet。
将众多pagelet加载的不同阶段像流水线一样在浏览器和服务器上执行,这样就做到了浏览器和服务器的并行化,从而达到重叠服务器端运行时间和浏览器端运行时间的目的。使用BigPipe 不仅可以节省时间,使加载的时间缩短,而且可以同过pagelet的分步输出,使一部分的页面内容更快的输出,从而获得更好的用户体验。BigPipe 中,用户提出页面访问请求后,页面的完整加载流程如下:

1) Request parsing:服务器解析和检查http request
2)Datafetching:服务器从存储层获取数据
3) Markup generation:服务器生成html 标记
4) Network transport : 网络传输response
5) CSS downloading:浏览器下载CSS
6) DOM tree construction and CSS styling:浏览器生成DOM 树,并且使用CSS
7) JavaScript downloading: 浏览器下载页面引用的JS 文件
8) JavaScript execution: 浏览器执行页面JS代码

初略看一下也许会好奇这个和刚开始说的那个没什么区别,但这8个流程属于一个pagelet,而多个pagelet 的不同操作阶段就可以像流水线一样进行执行了。

与ajax比较

1) AJAX 的核心是XMLHttpRequest,客户端需要异步的向服务器端发送请求,然后将传送过来的内容动态添加到网页上。如此实现存在一些缺陷,即发送往返请求需要耗费时间,而BigPipe 技术使浏览器并不需要发送XMLHttpRequest 请求,这样就节省时间损耗。

2) 使用AJAX时,浏览器和服务器的工作顺序执行。服务器必须等待浏览器的请求,这样就会造成服务器的空闲。浏览器工作时,服务器在等待,而服务器工作时,浏览器在等待,这也是一种性能的浪费。使用BigPipe,浏览器和服务器可以并行同时工作,服务器不需要等待浏览器的请求,而是一直处于加载页面内容的工作阶段,这就会使效率得到更大的提高。
3) 减少浏览器发送到请求。对一个5亿用户的网站来说,减少了使用AJAX额外带来的请求,会减少服务器的负载,同样会带来很大的性能提升。

缺点
不利于seo,针对爬虫需要通过ua判断,爬虫还是用传统模式,用户就用bigpipe

注意事项:
1.如果使用nginx作为web服务器,那么nginx可能会缓冲php的输出。即便是调用了flush方法,相应内容也会被nginx缓冲,而不会输出到浏览器。
2.某些浏览器也会有缓冲,如在接收的数据小于一定值的时候,不会对代码进行渲染。

补充:
php文件最终在浏览器上显示,走过3个缓冲阶段
即:php buffer=》web server buffer=》浏览器buffer

1)php buffer
php运行的结果先放入缓冲区(buffer),只有当缓冲区满了或者php运行完毕,才将数据输出去。
所以这边通过ob_flush将缓冲区的内容强制输出。

2)web server buffer
目前我们接触的也就apache和nginx
apache buffer
当php的数据给apache服务器时,也会想放入缓冲区(当缓冲区数据满或者执行完毕时,才执行数据)
这边我们可以在php层使用flush()来强制将缓冲区数据输出
(旧版本Apache可能需要关闭GZip。)

nginx buffer
nginx使用fastcgi缓冲区来缓存数据,fastcgi是强制将buffer打开的,无法关闭。
应对方法:通过apache+php实现bigpipe,nginx放在代理服务器的角色上,并使用proxy_buffering关闭代理缓存

3)浏览器buffer
这里研究得不深,不过这里指的不是讲图片,样式,头信息和js等缓存,而是和上面一样,将内容想放入缓存区中,当请求完毕和缓存写满后在输出。
这一层清楚方法未知,不过影响不是很大,一般主流的不超过4k。

实现代码
见附件

直接将txt换成php运行即可、
aaa

这边只是用php简单的实现其大概思想,但这样并不支持多线程,但对于小网站来说这样串行加载已经可以达到加载要求了。

对于大型网站,那么就需要考虑多线程执行这些pagelet。由于php不支持线程,所以可以使用的方式大致有curl,stream_select和php5新增的stream_socket_client函数或者用PHP 的扩展模块paaactnl模块中的pcntl_fork()函数来生成子进程。

——————————————————————————————

相关参考

http://www.searchtb.com/2011/04/an-introduction-to-bigpipe.html(bigpipe详细介绍以及相关bigpipe参考链接)
http://taobaofed.org/blog/2016/03/25/seller-bigpipe-coding/(bigpipe编程实践)
http://blog.sina.com.cn/s/blog_4dd475390102ebe6.html(bigpipe注意事项)
http://www.bo56.com/%E4%BB%8Ephp%E7%9A%84%E7%BC%93%E5%86%B2%E5%8C%BA%E8%AF%B4%E8%B5%B7/(从php缓存去说起)