带三点水的男孩名字Panda,一个热爱技术,喜欢刨根问底,热爱分享, 热爱开源的程序猿,活跃于开源社区,乐于分享交流。PHP 开源项目贡献者,对网络安全、PHP 内核、Nginx 内核、MySQL 有一些研究。本文来自作者在 GitChat 上分享 「2017 年 PHP 社区总结,2018 PHP 发展展望」主题内容。
注:一个 Web 站点可以会使用多种语言作为它的开发语言,本文含有不少从鸟哥 PPT 里的截图,图片版权归鸟哥所有。PHP 开始于 1994 年,最初产生于 Rasmus Lerdorf 的一个简单的想法,当时 Rasmus 用 C 语言写了一个应用程序,这个程序就是用来追踪和自己的个人主页的。并且 Rasmus 对其又进行了扩展,使其可以应用于 web 表单还可以和数据库进行交互。就这样 PHP 的第一个版本就诞生了。Rasmus 称其为 “Personal Home Page/Forms Interpreter” 简称 PHP/FI。用 Rasmus 自己的话说:起初并不想开发一门新的编程语言,但是随着 PHP/FI 的发展,渐渐的就不再受他的控制了。就这样一个开发团队行程了,并且在 1997 年的 11 月发布了第二个版本 PHP/FI 2。再往后,Zeev Suraski 和 Andi Gutmans 两个人的出现,更是使得 PHP 的发展了一个新的里程碑。1997 年,两人重新写了 PHP 的解释器,形成了 PHP 的第三个版本 PHP3,也就是在此时正式名字由 PHP/FI 改为 PHP(Hypertext Preprocessor 超文本预处理器)。时隔一年,两人在 1998 年又重新写了 PHP 的核心代码,用了将近一年的时间,Zend 引擎在 1999 年诞生了。接着在 2000 年 5 月,带有第一代 zend 引擎的 PHP4 正式发布了。随后其发展进入了一个平缓的阶段,带有第一代 Zend 引擎的 PHP4 在 2008 年 8 月达到 4.4.9 以后就再没有进行后续开发,也没有任何的安全更新。我用的最早的一个 PHP4 的程序应该是 DEDECMS 了。这时 PHP 还是面向过程的编程方式。在 2004 年 6 月份的时候,PHP 的发展到达了第二个里程碑。带有 Zend Engine II 的 PHP5 正式发布,在这 PHP5 中开始支持面向对象,而且性能明显增强。直到 2008 年很多程序都不再支持 PHP4 版本了,取而代之的是 PHP5。接着,下一个人物该出场了,他的出现使 PHP 从 5 又上升了一格成为了 PHP6。他的名字叫 Andrei Zmievski。当时 PHP5 发布以后,PHP 收到了各种各样的反馈,反馈的内容就是在 PHP 中缺少编码转换的支持。所以在 2005 年的时候,由 Andrei 领导在 PHP 中嵌入了 ICU 库。并且使文本字符串以 unicode-16 的方式呈现。这一举动,对于 PHP 本身以及用户的编码方式都产生了大的改变,所以 PHP6 应运而生了。虽说这一改变跨越很大,但是由于开发人员不能很好的理解所做的这些改变,并且向 unicode-16 编码(这一编码方式在 web 中很少被用到)转换会导致性能的下降,种种原因导致这一工程停滞下来。而且在 2009 年发布的 PHP5.3 还有 2010 年发布的 5.4 几乎涵盖了所有从 PHP6 移植来的功能。因此在 2010 年这项工程停止了,直到 2014 年也没有被人们所接受。在 2014-2015 年期间,PHP7 正式发布了。最初对于 PHP7 的这个版本是存在一些争议的,因为先前的 PHP6 并没有正式发布,就夭折了,所以直接到 7 这个版本并不是很合适。但是在一些学术论文还有书籍中已经引用了 PHP6 这个名称,所以说最终人们将其定位 7。对于 PHP7 其主要的目标就是通过重构 Zend 引擎,使 PHP 的性能更加的优化,同时保留语言的兼容性。由于是对其引擎的重构,因此 PHP7 的引擎目前已是第三代 Zend Engine 3。今天 PHP7 已经正式发布,纵观其从诞生到发展壮大,有成功也有失败,而今天的成功又仅仅源于昨天的一个简单的想法。
作为一名程序员,如果自己在现在的一个想法,多少年后也能产生如此大的成就,那岂是一个 “自豪” 所能表达的。类似的情况也发生在另一个人的身上,linux 的奠基者 linus。
不管怎么说,作为一名 PHP 程序员,看到 PHP 今天的成绩自然感到高兴,自己也会在 PHP 的上一直走下去,希望 PHP 的发展越来越好。
这里需要补一点点的 C 语言基础,辅助不熟悉 C 的同学理解。struct 和 union(联合体)有点不同,Struct 的每一个变量要各自占据一块的内存空间,而 union 里的变量是共用一块内存空间。
也就是说修改其中一个变量,公有空间就被修改了,其他变量的记录也就没有了。因此,虽然变量看起来多了不少,但是实际占据的内存空间却下降了。
当变量类型是 array、objec、string 等超过 64bit 的,value 存储的就是一个指针,指向真实的存储结构地址。
Zend_string 是实际存储字符串的结构体,实际的内容会存储在 val(char,字符型)中,而 val 是一个 char 数组,长度为 1,方便变量占位)。
结构体最后一个变量采用 char 数组,而不是使用 char*,这里有一个小优化技巧,可以降低 CPU 的 cache miss。
但是,如果使用 char*,那个这个存储的只是一个指针,真实的存储又在另外一片的内存区域内。
而实际上,当这些内存块被载入到 CPU 的中,就显得非常不一样。前者因为是连续分配在一起的同一块内存,在 CPU 读取时,通常都可以一同获得(因为会在同一级缓存中)。
而后者,因为是两块内存的数据,CPU 读取第一块内存的时候,很可能第二块内存数据不在同一级缓存中,使 CPU 不得不往 L2(二级缓存)以下寻找,甚至到内存区域查到想要的第二块内存数据。
在编写 PHP 程序过程中,使用最频繁的类型莫过于数组,PHP5 的数组采用 HashTable 实现。
如果用比较粗略的概括方式来说,它算是一个支持双向链表的 HashTable,不仅支持通过数组的 key 来做 hash 映射访问元素,也能通过 foreach 以访问双向链表的方式遍历数组元素。
这个图看起来很复杂,各种指针跳来跳去,当我们通过 key 值访问一个元素内容的时候,有时需要 3 次的指针跳跃才能找对需要的内容。
同理可得,在 CPU 读取的时候,因为它们就很可能不在同一级缓存中,会导致 CPU 不得不到下级缓存甚至内存区域查找,也就是引起 CPU 缓存命中下降,进而增加更多的耗时。
新版本的数组结构,非常简洁,让人眼前一亮。最大的特点是,整块的数组元素和 hash 映射表全部连接在一起,被分配在同一块内存内。
如果是遍历一个整型的简单类型数组,效率会非常快,因为,数组元素(Bucket)本身是连续分配在同一块内存里,并且,数组元素的 zval 会把整型元素存储在内部,也不再有指针外链,全部数据都存储在当前内存区域内。
图中,在 vm 栈中的指令 send_val 和 recv 参数的指令是相同,PHP7 通过减少这两条重复,来达到对函数调用机制的底层优化。
通过宏定义和内联函数(inline),让编译器提前完成部分工作 C 语言的宏定义会被在预处理阶段(编译阶段)执行,提前将部分工作完成,无需在程序运行时分配内存。
内联函数也类似,在预处理阶段,将程序中的函数替换为函数体,真实运行的程序执行到这里,就不会产生函数调用的开销。
PHP7 在这方面做了不少的优化,将不少需要在运行阶段要执行的工作,放到了编译阶段。例如参数类型的判断(Parameters Parsing),因为这里涉及的都是固定的字符常量。
因此,可以放到到编译阶段来完成,进而提升后续的执行效率。例如下图中处理传递参数类型的方式,从左边的写法,优化为右边宏的写法。
可空类型:主要用于参数类型声明和函数返回值声明;list 的方括号简写: 我们知道在 PHP5.4 之前只能通过 array() 来定义数组,5.4 之后添加了 [] 的简化写法;允许在 list 中指定 key;void 返回类型:PHP7.0 添加了指定函数返回类型的特性,但是返回类型却不能指定为 void,7.1 的这个特性算是一个补充;类常量属性设定;多条件 catch;详见 RFC 地址。3. PHP7.2 的变化
语法、函数方面更严格了,性能也有提升。详见 PHP 7 ChangeLog:。PHP 的性能演进 (从 PHP5.0 到 PHP7.1 的性能全评测):。PHP 周边优秀开源项目
目前最火热的 Laravel 类似 ROR 的语法,具有丰富的组件、活跃的社区、更多的语法糖;然后就是由华人开发的 Yii 框架,Gii 生成代码;还有国产的 ThinkPHP 快速上手;还有 codeigniter 简洁方便,还有 Phalcon 是用 C 语言开发的框架,以 PHP 拓展的形式,性能强悍、功能强大。2. 组件篇
国产的 Swoole 重新定义 PHP,异步、高性能;国产的 SeasLog C 拓展高性能的 Log 组件;在此强烈推荐大家看看 Symfony 这个框架解耦做到极致 , 每个模块都是一个组件 , 都可以单独拿出来使用;大家应该会和微信开发打交道 强烈推荐 EasyWeChat 封装适度、简洁的 API ;PHP-ml 是 PHP 的机器学习库,同时包含算法、交叉验证、神经网络、预处理、特征提取等。3. 工具篇
推荐 Composer,优秀的 PHP 包管理工具 , 有了它 , 你就可以把社区优秀的开源组件为自己所用;Psysh,这是我经常使用的,调试验证小段代码信手拈来 !
Xdebug 断点调试利器 , 让 BUG 无处可逃;Xhprof 专注于性能分析 , 找出你代码慢在哪里 , 持续优化 持续提高性能;Deployer 项目部署工具 简单 快捷 ;Piplint 新鲜出炉的 项目部署系统 国产 中文文档支持 ;更多有趣的 PHP 组件可以关注这个项目 awesome-php。4. 项目篇
Fecshop :基于 PHP Yii2 框架开发的一款优秀的开源电商系统,可持续发展的电商系统;zentaopms :国内市场市场占有率最高的项目管理 BUG 管理软件;OpenCart :国外电商适用的开源电商系统。PHP 在 Web 生态中的变化
正在开发中的 libpkd = 拓展语言原生能力,构建运行时标准库,目前已经基于 Swoole 生态涌出很多优秀的框架。
随着开源的流行 越来越多的 PHPer 在贡献自己的一份力量 GitHub 上 PHP 的开源项目越来越多,例如 packagist 上的组件越来越丰富,而且 PHP 语言本身的性能也在不断提升,让 PHP 语言换发出新的生命力。
网友评论 ()条 查看