ZT,PHP的缺点

ZT,PHP的缺点

ZT,PHP的缺点
ZT,PHP的缺点

作者: php5 发布日期: 2006-7-04 查看数: 520 出自: http://www.phpx.com

我在过去的四年里一直致力于PHP应用的开发。PHP确实十分容易编写。但是PHP也有一些十分严重的缺陷。

下面我会给出我的理由,为什么PHP不适合于比小型业余网站更大的网站。

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依然不流行的原因之一。

请阅读这篇讨论: Slashdot: Sites Rejecting 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同样是一个更好的选择。

[转贴自CSDN]

作者: 唠叨 发布日期: 200.
作者: 唠叨 发布日期: 2006-7-04
怎么把这么古老的文章又翻出来了?
除了2、3以外都是不是问题的问题。

1. 对递归的不良支持
除了lasp,现存的各种语言都不是递归的优良支持这
php有c书写,当然很自然的沿用堆栈来支持递归。况且堆也并不是可以无限制使用的

4. 没有命名空间
自c++引入类的概念起,这个问题已经得到了很好的解决
而java引入命名空间的概念,不能不说是败笔。java的创造者们声称他们只需要一个基类就可以解决任何问题,但事实证明不借助外部资源是不行的。

5. 不标准的日期格式字符
php同时支持多套 日期格式字符 ,因为只是作者不了解而产生误解

6. 混乱的许可证
扩展模块由扩展模块的开发这自行开发,很自然的就有商业许可证的问题。总不能因为这个就全盘否定开源吧

7. 不一致的函数命名规则
基于同样的原因,没有,也不可能有一个上帝来统一规划函数的命名

8. 魔法引用的地狱
魔法引用是php的一个亮点,虽然出于安全的考虑不建议使用。但他带来的便利是无庸质疑的。既然是要写出一个有弹性的脚本,那么检查总是必要的。不能因噎废食

9. 缺少标准框架
php的优势就在于没有框框。如果都象八股文似的,编程又有何乐趣而言呢

php是开发语言,而不是应用框架。
任何人都可以借助php这个工具不受约束的打造出丰富多彩的网站
作者: xuanmin 发布日期: .
作者: xuanmin 发布日期: 2006-7-04
9. 缺少标准框架
php的优势就在于没有框框。如果都象八股文似的,编程又有何乐趣而言呢

最支持楼上同志这句,我是非常鄙视什么框架不框架的,要它你还叫程序员吗



作者: lov 发布日期: 2006-7-04
9. 缺少标准框架
一个成长中的网站没有一个整体框架,最终会变成维护的噩梦。一个框架可以让很多工作变得简单。现在最流行的框架模型时MVC-模型,在其中表现层、业务逻辑和数据库访问都分离开了。

很多PHP网站不使用MVC-模型。他们甚至没有一个框架。甚至现在有一些PHP框架同时你都可以自己写一个,关于PHP的文章和手册没有提高框架的一个字。同时JSP-开发人员使用像Struts的框架、ASP开发人员使用.Net,看起来好像这些概念都广泛被PHP开发人员所了解。这就说明了PHP实际上到底是多专业。

楼主做了四年,可能一直都是soho吧,现在很多的PHP的团队都是使用MVC模型。
作者: 开花石头 发布日期:.
作者: 开花石头 发布日期: 2006-7-05

似乎除了2、3问题都不大,而且3的问题也不是没办法解决,每个语言有每个语言的特点,不能一概否定,现在的网站,很多都是多种语言并存开发,越大的网站这种情况越明显,因为他们都意识到了量材施用,不能说java好,那么我们所有的项目都用java,我们可以根据系统的特点,甚至采用不同的语言编写不同的功能模块,这样才是一套好的系统,虽然对于管理会有一定的难度,但是这点难度,和实际应用所需要的成本比起来,也是可以牺牲的

【某些商业程序除外,比如说,系统用java写成,可以多要几倍的钱】
【个人应用除外,因为自己喜欢哪个用哪个,哪个方便自己用哪个】
【小公司除外,因为没有钱为每种程序的编写雇用一个好的程序员】
【非纯技术公司除外,因为他们只是要使用程序】
【不赞同此观点的除外,萝卜白菜,各有所爱】
【。。。。。。好像都除外了】
作者: andot 发布日期: 20.
作者: andot 发布日期: 2006-7-07
我来补充两个 PHP 的缺点:

PHP 不支持资源类型的序列化(可以理解)。但是 PHP 的 Session 都是靠序列化保存的,因此 PHP无法在 Session 里保存资源对象,例如套接字、文件句柄等,而这些东西在 ASP.NET 中都是可以保存到 Session 中的。因此 PHP 不存在真正的 Session 级别的对象。

PHP 不支持 Application 级别的对象。在 ASP、ASP.NET、JSP 中都有 Applcation 级别的对象,因此可以很容易实现链接池这种东西,但是 PHP 没有提供这种机制,因此它无法用 PHP 语言本身来实现链接池,只能借助于 C 扩展,而这对于普通的开发人员是很难实现了。


作者: diekiss 发布日期: 2006-7-07
楼上的,虽然PHP不支持资源序列化,不过还是有很多方法去替代实现的。这就是PHP的灵活所在。


作者: andot 发布日期: 2006-7-07
楼上的,你既然说 PHP 在这方面有灵活所在,那你说说怎么创建一个 Session 级别的套接字,怎么创建一个 Application 级别的套接字。
作者: 唠叨 发布日期: 200.
作者: 唠叨 发布日期: 2006-7-07


QUOTE:
PHP无法在 Session 里保存资源对象,例如套接字、文件句柄等,而这些东西在 ASP.NET 中都是可以保存到 Session 中的。


呵呵,您是在单用户环境下工作吗?如果套接字、文件句柄等都可以持续存在,那么要挤占多少系统资源呢?
比如当把文件句柄保存在session中,那么文件就不需要关闭了。但是当多个人做此操作时,你将如何处理共享冲突呢?

QUOTE:
PHP 不支持 Application 级别的对象。在 ASP、ASP.NET、JSP 中都有 Applcation 级别的对象,因此可以很容易实现链接池这种东西,但是 PHP 没有提供这种机制,因此它无法用 PHP 语言本身来实现链接池,只能借助于 C 扩展,而这对于普通的开发人员是很难实现了


首先,链接池不是由Applcation创建的。而是数据库接口odbc、jdbc提供的。
其次 ASP、ASP.NET、JSP 都有自己专用的服务器软件,而php可以以cgi和模块这两种方式挂接在任何通用的web服务器中。若要提供 Application 的确非常困难。因为调度Application就必须有常驻内存的进程,而cgi方式就不可能常驻内存
用php模拟实现Application可以编程并以文件、数据库、共享内存做为载体。但基于上述原因也只能是模拟。





作者: andot 发布日期: 2006-7-07
既然提供不了,就说这东西没用的话,这不是吃不到葡萄说葡萄酸的表现吗?

能够保存套接字、文件句柄这类对象,不一定你就非要把它放到论坛里去用。对于一些企业应用系统来说,保存这类东西到一个会话里是必要的。我举个例子,比如 telnet 协议,如果你熟悉它的话,你会知道你如果用程序方式 telnet 登录到一台机器并在上面执行一些操作的话,从登录到执行完至少需要 5 秒钟的时间,如果每个请求都需要延时 5 秒,显然是不合适的,但是如果把一个已经完成登录的 Telnet 套接字保存到 Session 中的话,那么对于同一个用户的操作就可以避免每次都要进行登录这一步操作,这样一次请求的处理时间不到 1 秒钟,这显然提高了效率,另外,有些操作是有上下文关联的,在不能保存的他们的情况下,每个请求都要完整的执行一遍所有的操作,而如果能够保存,则只需执行一步操作即可。

所以可以保存和会不会乱用是两码事。楼上的显然是在混淆概念。如果能够保存没有用的话,那为什么 ASP.NET 和 JSP 都可以做到,而 PHP 做不到?

连接池不是由 ODBC、JDBC 提供的,每次都操作都向 ODBC 去申请一个连接,操作完了就释放连接,ODBC 不会替你保存这个连接,已备你下次申请时马上给你,它会立即释放掉跟数据库服务器的连接。对于 MySQL、MSSQL 这样的数据库,有没有连接池倒也无所谓,数据库本身就有很好的性能。但是你是否用过国产数据库,那种破烂数据库在不用链接池的情况下,用不了多少操作,它就会死掉。所以,这时你就必须自己编写连接池管理程序,在 JSP、ASP.NET 中因为有 Application 级别的对象,所以实现这样的连接池管理类很容易,但是 PHP 没有,所以用它根本无法实现。

说实话,我是个 PHPer,对 JSP 一向不喜欢,但是有些事,PHP 做不了的 JSP 可以做的,我们不得不承认,而不是把缺点当成优点来自欺欺人,这样的态度并不能让你进步的!




作者: andot 发布日期: 2006-7-07
http://test.coolcode.cn/phprpc_2.1/sample/telnet.html

我这里有个加密传输的 Web Telnet 程序,无需安装任何客户端,而是直接利用 PHPRPC for .NET 来实现的 Ajax 程序,这个利用的就是 Session 级别的套接字,如果用 PHP 这个东西就没法做。
作者: uuq 发布日期: 2006-7-08
什么时候的文章




作者: sanders_yao 发布日期: 2006-7-08
必须要存储资源类型吗?
把资源类型中要用到的数据缓存到库里和session同步如何?
作者: andot 发布日期: 2006-7-08
实际上不是保存不保存资源类型的问题,而是存在不存实际的 Session 级别和 Application 级别对象的问题。向一个建立好的套接字,你即使保存它,下次打开还能还原它,它也不是原来的东西了,只有在 Session 级别和 Application 级别持续保持它,才是正道。可惜 PHP 缺少这种机制,虽然它还是专门为 Web 而设计的,缺少这一点实在是它的不足。

而且这不是不能实现的, PHP 又不是只能以 CGI 方式运行,他可以在 Apache 上以模块方式运行,也可以在 IIS 中作为 ISAPI 运行,在这个级别,完全可以实现真正的 Session 和 Application,只是它没做罢了。