起因

前两天,打算使用PHP写一个 Github文件下载加速项目。加速下载的功能比较简单,就是接收客户端请求的网址,然后转发请求,最后将数据返回客户端。

项目最开始用的是Swoole,其是一个国人团队主导开发,异步、高性能的PHP协程框架。查阅Swoole的文档后,很快将代码写好。部署到服务器测试时却发现一个严重问题:对于大文件(例如超过1G的文件),客户端请求直接返回500错误,但服务端没有任何错误提示。

由于大文件大文件才会出问题,因此原因比较好找:Swoole的HTTP客户端需要下载文件后才能转发给客户端,因此内存超限的可能性最大。Swoole作者的回复验证了这个猜测。

由于Swoole的HTTP客户端不提供数据流对象,Swoole解决这个问题唯有自己写裸TCP连接。不敢保证自己能很快撸出没bug的HTTP客户端,于是最后转向了使用ReactPHP开发。

Swoole和ReactPHP

这是本人第一次接触Swoole和ReactPHP。由于功能比较简单,不管使用哪个框架,看一下大致文档,都能在半小时内把功能代码写好。然而Swoole和ReactPHP在PHP生态中属于不同的东西,因此使用体验上差别很大。

Swoole属于拓展/模块(extension/module),安装时麻烦一些。其实根据官网教程,本人在Mac和Linux上安装时都遇到了点小问题,需要额外安装openssl、php-devel等开发包才能正常编译安装。由于Swoole属于用C语言开发的拓展,理论上有更好的性能。但是,使用过程中遇到问题,调试和解决都比较困难。

ReactPHP属于软件包(Package),源码使用PHP编写,通过Composer安装即可在项目中使用。鉴于其使用PHP编写,因此社区开发活跃,功能丰富文档完善。并且其代码遵循PSR规范,浏览和调试源码也非常简单。

就初次使用上来说,ReactPHP的体验是优于Swoole的,不仅能很快实现项目功能,而且安装和调试都非常方便。

PHP的生态

个人认为,Swoole和ReactPHP折射了PHP生态的问题,即使用拓展还是使用软件包。

其实PHP有三套软件包生态:PEARPECLComposer。当然PEAR可以忽略不计:作为软件包,其托管的代码基本移植成了Composer包;作为拓展安装工具,pecl是pear的别名,直接用pecl就完事。所以PHP软件生态主要是两套:PECL和Composer。

Swoole是PECL的代表,ReactPHP则是Composer的代表,其分界点便是用C还是用PHP开发。就个人观点,是偏向于用PHP开发的Composer包的。不仅因为安装和使用简单,更因为这是PHP,优先the PHP way!国内部分PHP开发者盲目崇拜Swoole这类用C底层语言开发的东西,导致PHP开发者大会变成一群C大佬教PHP人员写PHP语言的奇葩现象。

要是问我支不支持Swoole,那肯定是支持的,因为这也是完善PHP生态的重要一环。但PHP拓展使用C语言开发,开发和测试麻烦,更导致一些人认为用C语言才是高端的倾向。就Swoole和ReactPHP而言,使用上区别便是用原生协程,还是PHP的生成器协程加Promise,对于熟悉协程的人员其实应该都是无障碍的,但是Swoole明显环境部署更麻烦,而且文档相对较少,遇到问题调试也不方便,不熟悉C语言的发PR都麻烦。

其实,PHP开发就应该写好PHP语言,用PHP语言完善PHP生态才是正统,即编写Composer才是PHP the right way。实际上Java、Python、JS等诸多语言都是用本语言开发软件包来丰富生态,而不像PHP这样要用到C语言来拓展功能。尽管Nodejs有gyp、安卓有NDK等使用C/C++开发的场景,但是极少数情况才会用到,没有PHP圈把C语言开发拓展作为天经地义的现象。

所以,本次尝试Swoole和ReactPHP,更坚定了本人今后尽量用Composer包的理念。如果真的羡慕底层的C,还不如转Golang。

总结

目前PHP不需要拓展、只用Composer包是不可能的,GD、CURL、Mysql、PDO等诸多常用功能全部以拓展提供,PHP开发者也已经习惯了这种模式。但我还是想说,这些东西不是PHP,更不应该是普通PHP开发者追逐的目标。PHP开发者应该还是要以写好PHP为己任。

参考

  1. PHP协程
  2. PHP Composer入门
  3. 创建自己的Composer包