前言
虽说PHP是世界上最好的语言,但是写出来的PHP代码却往往不是最美观的。究其原因,可能正式因为PHP简单易上手,适合快速迭代的特性,导致了我们沉浸在迅速完成需求迭代的窃喜中,却忘记了规范性、忽略了易维护性,给后人挖了无数的坑,后面维护起来简直想骂娘。各位PHPer不妨问一下自己是否曾经写过下面的代码?
【1】一个函数写了两百行甚至更多
【2】一个函数的参数有七八个甚至十几个
【3】单行代码/字符串最长超过了120个字符
【4】一个PHP文件写了几千行
【5】修改代码的时候没有把对应的注释也修改一下
【6】不使用web框架提供的封装,而是直接用$_POST, $_GET, $_SESSION这些全局变量
【7】……
其实以上问题,在我们的项目中真的全都存在。写出上面的代码并不会影响代码功能的正常运行,不过所谓前人栽树后人乘凉,杂乱的代码就像一堆杂草,后人维护一堆杂草远比一颗大树痛苦的多。这其中带来的效率损失恐怕很难量化。试想一下阅读一个500行的函数,其中的局部变量就定义了不下50个,你看到一个变量时,脑海中根本想不到这个变量代表的含义,又要回去找定义它的地方,一步步跟踪下来或许思路早就被打断了。如果阅读一个50行的函数,整个函数体在一个电脑屏幕就可以容纳,连鼠标都不用翻动就可以看到全部,这时心里会有多么舒坦。
一些反面的例子
【1】一望无际的函数参数
【2】写了20000多行的代码文件
【3】手拼SQL语句,“貌似”很便捷
【4】六层foreach嵌套
做出改变
曾经看到过很多开发组,意识到代码规范问题之后,会去制定自己的代码规范。曾经我们也希望所有的开发坐下来,大家友好地协商出一份统一的代码规范。然而,这么做第一是很花时间,第二是不够细致,讨论中很难涉及到编码中的所有方面,第三也是最重要的一点,根本无法达成一致……想必大家都听说过程序界的一个经久不衰的段子,就是编码应该用空格缩进还是用tab缩进。偏偏代码规范这种东西,它是没有标准答案的,你可以列出10条使用空格做缩进的好处,但马上就会有人提出10条使用tab做缩进的好处。“讨论”这种方式根本行不通。
要想让大家指定并遵循一个没有标准答案的“标准”,光靠讨论是出不来结果的,这个时候我们需要的可能就是“权威”以及“强权”。“权威”是指去寻找业界大牛们到底是怎么做的,把他们的做法作为我们的“标准”总归不会有错。“强权”则是指确定了“标准”以后,依靠开发leader去强推给组内所有人,没有讨论的余地。“权威”保证了代码规范的正确性,“强权”保证了代码规范的执行力。
谁是“权威”?
有了上面的思路以后,我们就要讨论一下谁的代码规范才能代表“权威”。平时使用PHP做Web开发,想必大家一定会用到各种PHP框架,例如Laravel,Symfony,Yii Framework,Zend Framework等等。作为全球知名的开源框架,这些框架里的代码应该是非常符合规范的。那么他们符合的是什么变那么规范呢?
其实随便一搜索你就可以找到了,绝大多数框架都遵循PSR(PHP Standard Recommendation)规范。PSR是由一个叫做PHP-FIG(Framework Interoperability Group)的组织通过*投票的方式制定出来的规范。早在2009年的一次PHP技术会议上,各个PHP框架的作者自发成立了PHP-FIG组织,该组织的主要目的是希望给各个框架作者们提供一些优秀的设计规范并希望各个框架统一遵守。因此PSR其实代表了框架的设计规范,包括但不仅仅是代码书写规范。
PSR规范目前有从PSR1、PSR2、……、PSR17(还在扩展中)等十几项规范,涵盖了PHP Web框架设计的方方面面。而我们最关心的其实应该是PSR1和PSR2,这两个所描述的正式PHP编码的规范。有兴趣的话大家可以去他们的官方网站瞧一下(http://www.php-fig.org/),包括目前都有哪些规范、哪些正在制定中、组织的介绍等等。
目前绝大多数PHP Web框架都遵循PSR2的代码规范。
除了PSR,还有什么PHP代码规范?
当我看到PSR规范的影响力时,基本已经确定使用它作为我们项目中的编码规范。不过本着科学的态度,我们还是要了解一下业界还有哪些其它的规范。
如果你是一个PHP的老手,可能以前经常会用PEAR管理PHP库(虽然目前PEAR已经完全被Composer盖住了风头)。PEAR也有一套自己的代码规范(链接:https://pear.php.net/manual/en/standards.php),PEAR规范应该属于PHP最早期的规范了,很多其他代码规范都从它演化而来。它的要求也是最为宽松的。
如果你听说过PHP代码检查与美化工具PHP Code Sniffer(https://github.com/squizlabs/PHP_CodeSniffer),那一定可以看到其中提供的MySource、Squiz、PHPCS规范。PHP Code Sniffer是一个叫Squiz的公司开源出来的工具,所以肯定要推荐一把自己公司使用的代码规范,即Squiz规范,该规范比PSR要严格很多。举个例子,下面的写法在PSR2中没有不符合规范,但是在Squiz中是不合规范的。Squiz规定,一个类内部需要引用自身的时候,不得使用类名,而是使用self。
class Test { public function getInstance() { return new Test(); // 符合PSR,但不符合Squiz规范,Squiz规范要求这里写为 new self(); } }
PHPCS则是PHP Code Sniffer工具自身的代码使用的规范,比Squiz稍宽松一些,但是依然比PSR严格很多。而MySource规范则是最严格的一个,用于该公司的MySource Mini项目,其中不仅有PHP规范,甚至还有JS和CSS的规范。一个工具竟然提供了三个自己公司的规范……
简单总结一下:
严格程度 PEAR < PSR < PHPCS < Squiz < MySource
流行程度 PSR > PEAR > 其他
实际上,除此之外还有一些PHP框架也提供了属于自己框架的规范,例如CodeIgniter(http://codeigniter.org.cn/user_guide/general/styleguide.html)。比较奇怪这个框架为什么没有加入PHP-FIG,不过这类框架自己定义规范一般都比较小众。如果你使用了CodeIgniter,那当然是建议遵循框架自身的规范。这里就不再详细研究了。
根据PHP Code Sniffer作者的推荐,如果你还不知道用哪个好,那就先尝试用PSR2吧!
如何行动?
其实在规范执行的过程中,我们最开始一定会碰到很多困难。比如自己本来的代码书写习惯和规范不一样,刚一调整的时候会有些别扭;动辄数十页的规范内容,根本记不住,怎么办?PSR2的代码规范链接如下:http://www.php-fig.org/psr/psr-2/,看上去滚动条很短,页面内容太多,实际上它们完全可以压缩在一张纸上。在组内项目开发中,把PSR2用中文稍加翻译(表达同样意思,中文语句比英文短很多),缩小一些字号,放在一张纸上打印出来,贴在办公桌上,时间久了自然可以养成一个好的习惯。此方法在项目组内实行一段时间后,效果喜人。
结语
写了一大长篇PHP代码规范,却没有出现任何规范的详细内容。主要因为一般在博客里面写的长篇大论的规范貌似大家都不喜欢看~作为“漫谈”,只是记录一下自己寻找一份“科学”的代码规范的过程。规范的内容有些可能与你平时的习惯不太一致,不过这就是各个PHP Web框架开发者一致的选择。
参考链接:
1. PHP-FIG官网 http://www.php-fig.org/
2. PSR2规范 http://www.php-fig.org/psr/psr-2/
3. PHP Code Sniffer https://github.com/squizlabs/PHP_CodeSniffer
4. SquizLabs官网 http://www.squizlabs.com/
5. PEAR代码规范 http://pear.php.net/manual/en/standards.php