你的PHP比我的烂,因为你只懂得抱怨

来源:岁月联盟 编辑:zhuzhu 时间:2010-01-26

抱怨你的工具,并不会让你的事情做得更好。

我前一篇的「PHP 开发迷思 (叁) – PHP 很糟糕?」,有网友写了一篇「 PHP 很烂」来回应。

我想说的是:对他来说, PHP 的确很糟,所以真的不适合他;因为他引用了别人停留在三四年前的 PHP 的观念来证明他对 PHP 的看法。还有,他看到的都是烂 PHP 程序。

不可否认, PHP 的确在先天上有所不足,只因为它诞生的太早,很多包袱无法轻易摆脱。即便 PHP 6 将会摆脱这些束缚,但时间点似乎太晚?

所以呢?难道研究 PHP 的人都是傻瓜吗?

当然不是。

我不想为 PHP 平反什么,我也不认为我能改变多少人对 PHP 的看法。这裡我只想把这些人认为 PHP 烂的地方做个说明,剩下的就交给大家自行评断。

版本问题

从 PHP 诞生以来有十五年了,真正被大家重视而开始运用的第 4 版则有十年了。

然而随着 PHP 5 的诞生,以及 2008 年 PHP 4 不再被官方维护,大部份的主机商也已经部署了 PHP 5 作为主要执行环境;虽然现阶段 PHP 5 还是会让 PHP 4 的程序能够执行,但是开发者的观念如果没有一起随着更新,那才是灾难的开始。

语言的设计本来就没办法一开始考虑周详, Java 如此, Python 也是如此,它们在重大改版时,部份语法及相关的核心组件上本来就会有所改变。而开发者如果没有适时去了解在新版本上的使用差异,那么跟抱怨一把生锈的斧头很难砍倒一棵大树有什么差别?

Unicode

Unicode 在最近这几年才开始被台湾的开发者所重视,在那之前 BIG5 大概是他们的恶梦吧。

先不管 PHP ,我们来看一下别的语言怎么处理 Unicode 。

Ruby: 就我粗浅的了解, Ruby 本身也不完整支援处理 Unicode ,但还是可以处理。

Python: 在 2.x 版也是透过 unicode 类别来处理,在 3.0 核心有直接支援。

那么 PHP 呢?

的确 PHP 本身没有很方便的方法来处理 Unicode ,但是不表示它不能用其他方法来处理:

mbstring: 多位元组的字串处理

iconv: 转换编码

PHP 6 以后则是直接把 unicode 放到核心函式裡。

当然 PHP 先天的限制,会让它在处理 Unicode 字串上无法像 Ruby 和 Python 那么直觉;但不表示我们不能透过其他方法将它封装起来,方便后续的开发。

在资料库上的 Unicode 问题也是如此, PHP 本身不处理这些,它只是透过 client 来取得资料库回传的资料,这在每个语言对资料库的实作都是一样的。

Magic Quotes

一开始 PHP 有 magic_quotes 只是为了方便处理要塞入资料库的字串,因为当时 PHP 开发者对于程序与资料库之沟通非常不熟悉。

然而,这只是资料分层处理的观念。

事实上我们根本不该对接收下来的资料做假设,如果输入的资料是「许功盖 (BIG5) 」,就让它保持「许功盖 (BIG5) 」;等到要存入资料库时,再让真正的资料操作函数 (或物件) 去处理它 (像是 PDO::quote ) ,而不是再用 addslashes() 或 stripslashes() 这种别扭的方式来存取资料库。

而从资料库取得资料时也是一样,因为我们用正确的方法塞入,所以它也会回传我们正确的资料,这在所有语言都是一样的!

所以后来的 PHP 5.3 版本就将 magic_quotes 废弃, PHP 6 则直接不支援。

而在这之前的版本所开发出来的程序,也都是该以 magic_quotes 保持关闭的状态来开发;遇到不确定 magic_quotes 是否开启时,可以参考官方手册的建议来取消它对程序的影响。

SQL Injection

某网友说:「填‘; shutdown — 就能打挂一票网站…,九成可能都是 PHP 写的」,又说「我知道 SQL (Injection) 是跨语言的问题,但是 PHP 就是偏偏特别容易写出有洞的程序 像这样 “SELECT * FROM User WHERE id = $user_id” 然后就毁了。」

我个人倒认为,有九成以上会有 SQL Injection 问题的,可能是传统的 ASP 网站。 (这边 ASP 只是举例,不表示真的九成以上都是这样;事实上没有引用一个正确的统计数字,这都只是嘴炮而已,请塬谅我用这么粗俗的字眼)

从他写的程序可以看得出来,如果他用的语言没有一个正确的工具,那么他还是有可能写出有 SQL Injection 的网站。

其实上面提到的 magic_quotes 的目的之一,原来也是要解决 SQL Injection 的问题,但显然我们有更好的方法来处理它。另外基本的输入资料过滤也非常重要,设一道关卡来检查输入的正确与否本来就是程序设计师该做的;或许你可以用 Application Firewall 来完成,可是程序本身的防範措施才是最根本的解决之道。

语言本身帮我们做到一切当然是最好,但这不表示一位优秀工程师该把原本就有的技术与观念全都依赖在工具上。

Web Framework

某网友说:「 PHP 一般要写一周的网页程序,可能我用 Python + TurboGears 一天就能写完」,也有网友说:「 Xdite 用 RoR 一晚上就写好莫拉克风灾支援网」。

有趣的是,一个热血又熟悉 CakePHP 或 CodeIgniter 的 PHP 开发者也可以做到同样的事。

重点有叁个:

PHP 也有 Web Framework 。

对这个 Framework 够不够熟悉。

有没有热血。

Web Framework 是在这三四年来 Web 开发方向趋于明显时的产物,它可以说是一个语言想通往 Web 开发的钥匙。所以像 Python 上的 Django 及 TurboGears 、 Ruby 上的 RoR 等,都是展现语言特色的优秀框架。

回头来看看 PHP ,它在定义上也只是一个可以用来开发 Web 的 Script 语言;拿 TurboGears 来跟 PHP 比较,层级上实在是差太多了! PHP 在 Web 开发的门槛是很低,但不表示它就是没有效率、不够安全!因为这些都是开发者该去注意的!任何语言都一样!任何号称可以快速建置网站的开发者,只不过仰赖着 Web Framework 帮他们处理掉一些塬本是他该注意的事情而已。

换个角度来看,如果不依靠 Framework ,而有能力在一天之内用 Python 或 Ruby 语言本身硬刻出一个安全又快速网站的人,我想也是万中无一吧。注:事实上只要能跟 Web Server 沟通,就连 VB 或批次档都可以用来写 CGI ,但真的是太麻烦了。

结论

语言本身没有好坏之分,因为所谓的烂不烂都是决定于怎么用它来开发的人。任何工具一定有用得顺手和用得不顺手的问题,看开发者用什么样的心态去面对而已。

依赖语言或框架本身的优势的确很方便,但一旦脱离了它们,却无法保证能开发出好的程序,这不是一个优秀的工程师。

我不否认 PHP 确实有缺陷,但我不倾向去抱怨它们。了解它的优缺点,正确的使用它才是身为 PHP 开发者所应该走的方向。

一切都是开发者本身的问题。

作者:jaceju 原文地址: