若干年前,PHP5由面向过程转变为面向对象语言,在各个技术论坛上掀起了滔天大浪,很多人断言PHP自取灭亡,但不久之后尘埃落定,大部分人由不支持转向支持,PHP也由4.0时代被人戏称为小孩子的玩具,摇身一变而成为仅次于java和c的第三大语言。身处整个争论过程,我自以为对面向对象有了完整的认识,并逐渐开始全面采用面向对象方式编程,2008年以后,甚至开始只在zend framework框架下编写程序。
但最近数月的工作经历让我开始反省,我开始重新思索那个当年最著名的问题:“如果真的完全面向对象,我们何不直接使用JAVA?我们为什么需要两个JAVA呢?”是的,用PHP,理由之一,就是我们不一定要面向对象。一切编程技术和编程理念都只是手段,用最短的时间达成客户需求,才是我们的目的所在,抛开这一目的而空谈任何技术,都无疑是错误的,一个很典型的例子,开源的论坛程序中,所有PHPER人人都推崇PHPBB,而对DISUCZ的代码技术含量嗤之以鼻,可是,真正建论坛的时候,我们谁用PHPBB了?国内的大半论坛,都是DISCUZ的。近两年多时间,我都拘泥于面向对象,而浪费了大量的时间,这是我犯下的一个严重错误。
所以,我决定重新梳理一下我对PHP编程的认识,以后在项目选型时可以选择更合适的架构而不是唯技术是从。欢迎大家拍砖。
一、函数的作用
时至今日,任何一个非计算机专业的朋友也都该学过一门计算机语言,在国内,通常是basic,如果足够幸运,也可能是C,分支语句和循环语句是其中的必修内容,而如果函数学得不好,估计马马虎虎,也就过去了。哪怕世上没有函数这种东西,程序一样可以完成所有的功能(天可怜见,最近几个月,我刚刚见识了这样一个项目)。
那么,我们要函数什么用呢?无数教科书告诉我们,是为了可复用性。是的,一个函数写完之后,下次用到同样功能,直接调用就可以了,不用再重新写一遍了,这是函数发明的本意和基本功能。可是,如果我们预计一个功能不那么常用,是不是就该不用函数了呢?不是的,哪怕是采用面向过程的编程方式,我们仍然要尽可能的使用函数,并尽可能的细分功能,为每个功能写一个独立的函数。采用函数编程,有以下几个明显的优点:
逻辑清晰。无论多复杂的功能,当它被细分再细分,成为多个单一功能之后,每个单一功能的逻辑都是非常简单的,我们可以很轻松地根据逻辑填写代码而不必再为此劳神费力;
测试方便。用函数写程序,事实上是给程序做了天然的中断,我们能很迅速地知道,是哪段代码发生了错误。每个程序员心里应该都清楚,我们测试代码所花费的时间,通常两倍甚至三倍于我们编写代码的时间。
阅读轻松。当一个程序写完一段时间之后,客户在使用时发现问题,或是需要更改功能,程序员对哪怕是自己编写的代码,也未必就能记忆清楚,而阅读主要由函数编写而成的程序时,主程序基本上就是一个大纲,我们能够顺着主程序的脉络很迅速地找到相应的功能函数。
简单复用。通常,一个函数完成时必然是经过测试的,只要当时的测试仔细一点,以后,就可以假定这个函数是正确的了,随时根据函数说明调用就行,不必再关注其中的细节。
修改快速。有时我们也不能避免一些功能上的修改,当你的多个程序里调用同一个功能函数时,只要修改这个函数,所有地方都会同时改变,而不再需要逐一修改。
因为有了以上优点,采用函数进行面向过程方式编程,是所有人公认的方法,从来都没有见到哪个论坛有人提出质疑过。
二、代码注释
和很多人的习惯不同,我是喜欢大量注释的,而且是符合phpdocument标准的注释,这样,当我或者同事用zend studio或是netbeans之类的专业编辑器打开代码时,输入首字母,会自动跳出我所编写的函数和方法,然后就能看到我用中文注释的函数功能、用法、参数要求和返回格式。每个程序员都希望接手的代码注释越多越好,但很多人自己却很少写注释,我在论坛和QQ群里了解到了一些言论,发现这多半不是懒惰造成的,不写注释或少写注释,更多是出于对失业的恐惧和缺乏基本的自信,以至于期望别人难以接手从而保证自己的职位稳定。
三、用类取代函数
终于说到面向对象编程的基本方式了,在类里面,我们把变量称为属性,把函数称为方法,老外每提出一个新的概念就总喜欢做一些新的命名,这样做的好处在于,当年我们提到属性和方法时,总是显得比那些说变量和函数的人有学问。当然,实质上,它们完全是同一回事。
为什么要用类,按我个人的理解,最初,这多半是因为变量的作用域造成的。全局变量的安全性在C语言的入门教程里就开始提及的,不仅仅是容易产生漏洞被黑客入侵,更多的时候,自己编写代码时,也会因为全局变量的同名而产生各种预料不到的麻烦。而如果用参数传递每个变量,则会显得很累赘。由于有了netbeans这样卓越的编程工具,事实上,我并不用手工输入这些变量,而只是看着不爽而已。明明是多数函数或至少是一组函数都会用到的变量,偏偏要反复传值,总会觉得不舒服。于是,就有了类,并且,在PHP5.0之后,可以在类里面详细地定义属性(变量)和方法(函数)的作用域。
同时,用类的另外一个基本好处,就是可以把函数分组。当函数足够多的时候,会很难寻找,根据功能按类把函数分开,那些只供其他函数调用而不需要用户直接调用的方法,干脆设为私有,免得同事不慎调用出错,这样,一个公共的函数库就被完全分解为多个类了。
很多时候,一个类具备的基本功能是有普遍价值的,我们可以把一个类从一个项目中复制到另外一个项目,而完全不用担心出什么差错,这是没有自己属性值和作用域的函数组所无法做到的。
在这里,需要澄清的一个问题是,很多人都误认为把一个函数库分为多个会加速程序运行,他们的理解是每次页面只调用自己用到的那个函数库或是类,文件的容量小了,速度自然就快了。其实,实际情况是相反的,我们平时用电脑都知道,第一次打开一个WORD文件时,速度可能会比较慢,而关闭后不久第二次打开,速度就会快很多,这是因为,那个WORD文件和WORD软件本身,都被缓存到内存里了。同样道理,一个函数库,再怎么样也大不到哪里去,页面第一次调用时被缓存,接下来再次打开自然就快了很多;同时,如果一个页面本来包含一个函数库够了,如果分解后变成需要包含多个,文件寻道比加载需要花费更多的时间,所以即使是没有缓存的情况下打开页面,把一个函数库分解后,也会降低程序的执行速度;另外,类的实例化也是需要一定时间的。当然,以现在的计算机硬件而言,这些速度上的损失,是完全可以忽略不计的,所以,硬件的发展,也是面向对象方式编程开始流行的基础之一。
所以,在面向过程的程序中,我们还是会使用类,当然,在面向过程的程序中,只在三种情况下需要用类:
项目足够大,大到一个函数库会把人绕晕的时候;
我们发现自己写的某项功能具备通用性的时候;
我们调用之前写的类或是别人在网上发布的开源类的时候。
使用简单的类之后,你仍然不能宣称你的网站是面向对象的。我刚刚在这个帖子的标题后面加了个“(上)”,也就是说,在本文接下来的篇幅当中,我们仍然只谈面向过程中就可以使用到的技术,当然,它们也同样适合于面向对象。我将在下一个帖子里表述我对面向对象的理解。
四、模板
大名鼎鼎的smarty,就算没用过,也一定都听说过吧。最早是通过xoops认识它的,当时只做过简单留言板的我,学习SMARTY可以说是费了九牛二虎之力。记得那时找到的最好的SMARTY网络教程是大师兄smarty教程,好不容易搞懂了,过了一段时间,喜悦国际村里的兄弟们合伙翻译了整个smarty文档,但就在那时,我决定放弃smarty了,因为我坚持认为,{$x}和42501f36ea858627f36e47712971aeef没有任何区别,所谓模板,include就足够了,为了少打几个字母而去采用这么大一个家伙,是相当不值得的。嗯,这里解释一下我当初,哦,直到现在还有时候有用到的简单PHP模板用法吧:
文件demo.php: 48 49 view plaincopy to clipboardprint? 50 <?php 51 $userName='张三'; 52 include_once 'templates/demo.phtml'; 53 ?> 54 <?php 55 $userName='张三'; 56 include_once 'templates/demo.phtml'; 57 ?> 58 文件demo.phtml: 59 60 view plaincopy to clipboardprint? 61 <html> 62 ...... 63 <body> 64 你好,<?php echo $userName;?> 65 </body> 66 </html> 67 <html> 68 ...... 69 <body> 70 你好,<?php echo $userName;?> 71 </body> 72 </html>
看看,啥技术也没用,不也是一个模板吗?有段时间每次论坛里有讨论smarty时我总要推销一下我的想法,可惜人微言轻,一直没什么响应,直到前年,cakephp传入中国,所用的模板技术和我的想法大有异曲同工之妙,不久之后,zend推出了自己的框架,也是同样用了PHP来做天然的模板,同年,smarty不再作为php的核心子项目开发,如果大家访问http://smarty.php.net , 就可以看到一段提示:
76
77 Smarty is no longer a subproject of the PHP project, and has subsequently moved to its own domain: www.smarty.net
78
79 所以,页面和程序分开是绝对必要的,但是,以smarty为代表的模板技术则是没有必要的,除非你做开源程序或是做自助建站,没有办法控制模板的安全性,否则,就完全不需要使用模板。
80
81 五、生成静态页面 VS 缓存+伪静态
82
83 刚开始用PHP建站时,我用到的第一个CMS系统,名字叫9466 article,其中的生成静态HTML技术让我惊叹不已,虽然当时的版本还有很多功能上的不足,我还是花了很大的力气去修改和学习它,并把我的修改发布到了网上,神奇的是,刚刚google了一下"9466 slime修改版",竟然还有好些网站提供下载,2006年,我为一家企业做了个网站,网址是http://www.nbssdz.com ,这次是自己从头写的CMS,也同样用到了生成静态页面技术。但是,现在,我已经不再用这种技术了,joomla、phpwind、discuz和zend framework等等开源程序给了我们另一种技术演示:伪静态。
84
85 生成静态页面的好处有两个,一是提高网站访问速度,减低服务器负荷,二是优化搜索引擎,让搜索引擎收录更多本站页面。静态页面的缺点,当然就是“静态”。听上去好象是废话,但是,很多动态的功能在静态页面上是无法实现的,比如根据用户权限不同显示不同内容。所以,现在开始流行伪静态。伪静态的作用,顾名思义,就是为动态页面伪造静态网址,以吸引搜索引擎收录,我的网站http://www.10000j.com ,由于基于zend framework编写,所以天然具备伪静态功能,当然,默认的网址目录格式太深不利于收录,我会在年后抽空进行改变,我的另一个网站作品:http://czj.kiloweb.cn 对目录格式进行了优化,大家可以看到,链接格式的定制,是非常灵活的。当然,伪静态的服务器负荷,不但高于静态页面,甚至也高于普通动态页面,所以,我们必须灵活使用缓存来提高网站响应速度,即便如此,在响应速度上,伪静态仍然不占优势。
86
87 所以,对于功能要求不多的传统内容发布类,服务器负荷过重的网站,我们仍然可以使用生成静态页面技术,而对于有权限、点击计数等要求并需要长期维护经常性增加功能的甚至是有独立服务器的网站,则应该使用伪静态技术。毕竟部分功能时静态页面无法实现的,就算一些功能可以"想办法"实现(比如通过ajax和iframe),“想办法”所付出的时间成本,也太过高昂了。
88
89 六、ajax
90
91 ajax是一项振奋人心的技术,但AJAX的不便之处在于,网站的代码量大大增加了。最近一个项目中,由于页面采用了gb2312,而我采用的jquery框架的load()函数只支持utf8,所以我不得不使用iframe,然后我发现--嗯,这话说得有点神奇,用了那么多年iframe,又用了近两年的jquery,居然才发现--其实iframe也不错,而且让我少写了很多代码。最近一年多,我用jquery做了很多让老板郁闷的事情:我做了一些客户从来没有要求过的特效,只是因为这样在技术上比较炫,从而浪费了大量时间,并且让不懂jquery的美工和老板自己无从下手修改。所以,我要说的是,ajax是很好的东西,jquery是第一流的ajax框架,但是,好东西一样不要滥用,还是要从实际情况出发,有需求,才使用,而不是向我之前一段时间那样,有需求要用,没有需求创造需求也要用。
92
93 七、xml和json
94
95 常在论坛混的好处在于,总能及时知道流行技术的发展动向,比如,前年的某一天,很多人突然开始提出,用json来代替xml。我是举双手支持这个建议的。使用json除了提高访问速度之外,开发效率也会有大幅的提高。json_encode()
96 、json_decode(),就这么两条简单的函数,就能够轻易地在PHP数组和json直接进行转换,远远比simplexml和dom方便得多。所以,大多数时候,我们既不是做google的sitemap,也不是做rss,只是和jquery传一下值罢了,就用json吧,根本没有必要用xml的。
以上就是PHP编程方式的重新思索(上)的内容,更多相关内容请关注PHP中文网(www.php.cn)!