基于PHP一些十分严重的缺陷详解


Posted in PHP onJune 03, 2013

1. 对递归的不良支持
递归是一种函数调用自身的机制。这是一种强大的特性可以把某些复杂的东西变得很简单。有一个使用递归的例子是快速排序(quicksort)。不幸的是,PHP并不擅长递归。Zeev,一个PHP开发人员,说道:“PHP 4.0(Zend)对密集数据使用了栈方式,而不是使用堆方式。也就是说它能容忍的递归函数的数量限制和其他语言比起来明显少。”见bug 1901。这是一个很不好的借口。每一个编程语言都应该提供良好的递归支持。
2. 许多PHP模块都不是线程安全的
在几年前,Apache发布了Web服务器的2.0版。这个版本支持多线程模式,在这个模式下,软件一个一部分可以同时运行多个。PHP的发明者说PHP的核心是线程安全的,但是非核心模块不一定是。但是十次有九次,你想要在PHP脚本中使用这种模块,但这又使你的脚本不能合适Apache的多线程模式。这也是为什么PHP小组不推荐在Apache 2 的多线程模式下运行PHP。不良的多线程模式支持使PHP常被认为是Apache 2依然不流行的原因之一。
3. PHP 由于商业原因而不健全
通过使用缓存,PHP的性能可以陡增500%[见基准测试]。那么为什么缓存没有被构建在PHP中呢?因为Zend——PHP的制造者,它在销售自己的Zend Accelerator,所以当然,他们不想抛弃自己的商业产品这块肥肉。
但是有另一个可选择的: APC. (Zend后来推出Zend Optimizer,免费的加速器——译者)
4. 没有命名空间
设想某个人制作了一个PHP模块用来阅读文件。模块中一个函数叫做read。然后另一个人的模块可以读取网页的,同样包含一个函数read。然后我们就无法同时使用这两个模块了,因为PHP不知道你要用哪个函数。 但是有一个很简单的解决方法,那就是命名空间。曾经有人建议PHP5加入这个特性,但不幸得是他没有这么做。现在,没有命名空间,每个函数都必须加上模块名作为前缀,来避免名称冲突。这导致了函数名恐怖得长,例如xsl_xsltprocessor_transform_to_XML让代码难于书写和理解。
5. 不标准的日期格式字符
很多程序员对 日期格式字符 都很熟悉,它是从UNIX和C语言中来的。其他一些编程语言采用了这个标准,但是很奇怪的,PHP有它自己的一套完全不兼容的日期格式字符。在C中,“%j”表示一年中的当天,在PHP中他表示一个月中的当天。然而使事情更混乱的是:Smarty (一个很流行的PHP模版引擎)的 strftime 函数和 date_format 函数,却使用了C/UNIX的格式化字符。
6. 混乱的许可证
你也许认为PHP是免费的,所有的在手册中提到的PHP模块也是免费的。错了!例如,如果你想在PHP中生成PDF文件,你会在手册中发现两个模块:PDF 和 ClibPDF。但是这两个都是有商业许可证的。所以,你所使用的每个模块,你都要确保你同意他的许可证。
7. 不一致的函数命名规则
有些函数名称是有多个单词组成的。一般有三种单词组合的习惯:
直接拼接:getnumberoffiles
用下划线分开:get_number_of_files
骆驼法则:getNumberOfFiles
大部分语言选择其中一中。但是PHP都用到了。
例如,你想要把一些特殊字符转换成HTML实体,你会使用函数htmlentities (直接拼接单词)。如果你要使用相反的功能,你要用到它的小弟弟html_entity_decode。由于某些特殊的原因,这个函数名是由下划线分隔单词。怎么能这样呢?你知道有一个函数叫strpad。或者他是str_pad?每次你都要查看一下到底这个符号是什么或者直接等他出现一个错误。函数是不分大小写的,所以对于PHP来说rawurldecode 和RawUrlDecode之间没有什么区别。这也很糟糕,因为两个都使用到了同时他们看上去还不一样,混淆了阅读者。
8. 魔法引用的地狱
魔法引用(Magic quote)可以保护PHP脚本免受SQL注入攻击。这很好。但是出于某些原因,你可以在php.ini中关闭这个配置。所以你如果要写出一个有弹性的脚本,你总要检查魔法引用是开启还是关闭。这样一个“特性”应该让编程更简单,而事实上变得更复杂了。
9. 缺少标准框架
一个成长中的网站没有一个整体框架,最终会变成维护的噩梦。一个框架可以让很多工作变得简单。现在最流行的框架模型时MVC-模型,在其中表现层、业务逻辑和数据库访问都分离开了。
很多PHP网站不使用MVC-模型。他们甚至没有一个框架。甚至现在有一些PHP框架同时你都可以自己写一个,关于PHP的文章和手册没有提高框架的一个字。同时JSP-开发人员使用像Struts的框架、ASP开发人员使用.net,看起来好像这些概念都广泛被PHP开发人员所了解。这就说明了PHP实际上到底是多专业。
总结
什么问题?
对于非常小的项目,它可以是一个十分符合人意的编程语言。但是对于较大的和更为复杂的项目,PHP就显出他的薄弱了。当你不断地摸索之后,你会发现我提到的某些问题的解决方案。所以,当解决方案已知之后,为什么不能修正他呢?另外为什么这些修补不在手册中提到呢? 一个开源的语言十分流行是一件好事。但不幸得是,它不是一个伟大的语言。我希望所有的问题能有一天得到解决(也许在PHP6?),然后我们就将拥有一个开源语言,他既开源,又好用。
到现在,当你要启动一个多于5个脚本页面的项目的时候,你最好考虑C#/ASP.NET或者 Java/JSP或者也许Python同样是一个更好的选择。

PHP 相关文章推荐
把PHP安装为Apache DSO
Oct 09 PHP
PHPnow安装服务[apache_pn]失败的问题的解决方法
Sep 10 PHP
PHP 提取图片img标记中的任意属性的简单实例
Dec 10 PHP
php命名空间学习详解
Feb 27 PHP
PHP调用VC编写的COM组件实例
Mar 29 PHP
php获取客户端电脑屏幕参数的方法
Jan 09 PHP
php数据库操作model类(使用__call方法)
Nov 16 PHP
php生出随机字符串
Jul 06 PHP
对于Laravel 5.5核心架构的深入理解
Feb 22 PHP
PHP后期静态绑定之self::限制实例分析
Dec 21 PHP
laravel自定义分页的实现案例offset()和limit()
Oct 15 PHP
PHP 代码简洁之道(小结)
Oct 16 PHP
spl_autoload_register与autoload的区别详解
Jun 03 #PHP
基于Linux调试工具strace与gdb的常用命令总结
Jun 03 #PHP
linux命令之调试工具strace的深入分析
Jun 03 #PHP
如何使用Strace调试工具
Jun 03 #PHP
鸡肋的PHP单例模式应用详解
Jun 03 #PHP
phpize的深入理解
Jun 03 #PHP
PHP不用第三变量交换2个变量的值的解决方法
Jun 02 #PHP
You might like
PHP禁止个别IP访问网站
2013/10/30 PHP
PDO防注入原理分析以及使用PDO的注意事项总结
2014/10/23 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
javascript 动态修改样式和层叠样式表代码
2010/04/27 Javascript
jquery.artwl.thickbox.js  一个非常简单好用的jQuery弹出层插件
2012/03/01 Javascript
js关闭子窗体刷新父窗体实现方法
2012/12/04 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
2013/11/14 Javascript
javascript通过className来获取元素的简单示例代码
2014/01/10 Javascript
详解JS函数重载
2014/12/04 Javascript
JavaScript检测浏览器cookie是否已经启动的方法
2015/02/27 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
javascript显示上周、上个月日期的处理方法
2016/02/03 Javascript
DOM 事件的深入浅出(一)
2016/12/05 Javascript
手机软键盘弹出时影响布局的解决方法
2016/12/15 Javascript
JQuery validate 验证一个单独的表单元素实例
2017/02/17 Javascript
js eval函数使用,js对象和字符串互转实例
2017/03/06 Javascript
Angular 4.0学习教程之架构详解
2017/09/12 Javascript
[原创]js实现保存文本框内容为本地文件兼容IE,chrome,火狐浏览器
2018/02/14 Javascript
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
2020/11/12 Javascript
python中print()函数的“,”与java中System.out.print()函数中的“+”功能详解
2017/11/24 Python
Python自定义函数定义,参数,调用代码解析
2017/12/27 Python
浅谈Python实现2种文件复制的方法
2018/01/19 Python
HTML5 Plus 实现手机APP拍照或相册选择图片上传功能
2016/07/13 HTML / CSS
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
医院后勤自我鉴定
2013/10/13 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
三提三创主题教育活动查摆整改措施
2014/10/25 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
拾金不昧感谢信范文
2015/01/21 职场文书
MySQL主从复制断开的常用修复方法
2021/04/07 MySQL
Vue h函数的使用详解
2022/02/18 Vue.js