PHP网站设计平台在最近几年变得非常流行。PHP的简单,易学,易用让很多新手都愿意接受它。然而,PHP也有一些严重的缺陷,到底哪些是会导致PHP被改写的缺陷呢?这篇文章是针对PHP缺陷可能引起的一些潜在的问题,和一些已经发生的问题而写的。同时,也将提出一些促进这个平台改进的观点。 简介 PHP始于拉斯姆斯·乐道夫1994年创建的一套小的通用网关接口,在经过几代改动之后,如今的PHP成为了最流行的网站设计平台。有许多客观的原因使它如此受欢迎。PHP是非常简单的,易学易用的,开源发布的独立平台。PHP能够很容易的支持当下任何种类的Web服务器。 PHP脚本能被非常快速地执行,并且PHP资源在Web上有很大的自由空间。 同时,PHP平台也有许多严重的缺陷,其中的一些并没有被广泛的关注过。忽视这些缺陷将导致低劣的程序设计。另一个严重的问题是基于PHP的Web应用是有安全风险的,主要是由于很糟糕的程序设计和PHP典型程序设计技术的不恰当运用。 正文 大部分缺陷的产生,是因为PHP缺少可靠和一致的初始设计。为了克服这个问题,PHP的开发团队几乎都会为每个新的发行版本更改说明书。因此,PHP平台被不断地改进,但是,一些向后兼容的问题也显现了出来。当PHP被当做LAMP(Linux-Apache-MySQL-PHP)中的一部分运行时,一些问题就体现出来了,我们根据缺陷的来源和范围,将它分成了几类:典型的问题和缺陷,异常的PHP环境。 1. 来自于语言初始设计和概念的问题。PHP语言的初始设计目的是为Web服务器脚本提供一个非常简单易用的环境。一些脚本语言的典型特征肯定会使PHP面临更严峻的挑战。 1.1.PHP没有严格的变量类型。在PHP语言中,没有严格的数据类型,变量必须在使用之前被申明。这样一来,变量的使用和管理就变得很复杂了。这是对那些经验不足的程序员来说是一件糟糕的事情,这很可能导致一些漏洞的产生,而且还很难发现他们。遗憾的是,这个问题不大可能在PHP中解决,因为这要改变PHP语言最基本的设计思想。 1.2.注册全局变量。PHP这种程序设计技术使参数的请求操作变得简单,给程序员带来了方便。然而,当"register_globals"操作随着HTTP请求变量注入到脚本时,这种特征的益处并不比它的缺陷造成的风险更大。另外一个事实是PHP不能要求变量初始化,这种特性给了黑客理想的机会,将恶意代码用像cross-site脚本文件注入这样的技术渗入脚本中。这种来自于全局变量自动注册的威胁是众所周知的。很令人遗憾,即使最近的发行版本-PHP5也包含有这种特性。直到PHP6发行,全局变量自动注册的功能才被取消。 但是这本是很久以前就应做出的改变。现在很多的应用都依赖于这种特性,在PHP6.0平台上也将要遇到同样的问题。也许有一个好的方法,那就是限制include()和require()的功能,只允许使用本地文件,并以此来避免远端文件的注入。需要进一步说明的是,要建立一种方法来强迫用户无论何时都要过滤输入和输出,这将有助于避免SQL注入和其他各种常见的问题,这也将是一个非常受欢迎的改变。 1.3外设的可靠性为了执行一些重要的任务,PHP需要依赖外部设备,这将削弱平台的独立性和可移植性。一个很好的例子就是,当一个实时的工作需要被基于PHP平台的Web应用程序执行: 例如,一个通高邮件必须在每晚的20:00被准时的发送给系统管理员,或者每三个小时都必须执行系统状态检测。这些工作仅仅使用外部工具就能够执行,这是以LAMP为代表的Linux克隆服务器典型应用。这个克隆服务器提供了很好的接口和足够的功能。 它的缺陷是,如果很多的Web应用程序都在同一个服务器上使用克隆服务器,这必然将互相干扰。转移Web应用程序到另一个服务器上则必将带来兼容性问题。 1.4导致低劣的程序设计PHP脚本并不是最优化的预编译程序。每个PHP对象都有一个字节的头部,程序每次运行的时候都不得不从语法上从头进行分析,除非Zend最优化或者开销被用了。这就是为什么PHP没有鼓励使用模块化程序设计法的原因。 它的对象向导模块也不是非常的可靠。PHP平台的主要开发者认识到PHP类的列示要比Java花费了更多的时间。 PHP最大的一个优点就是速度,但是程序员不能快速有效的使用对象向导。 因此老式的程序扥设计风格就被重新使用了,这对小的简单的项目也许是一个好的解决方法,但是用在高级别的项目上则完全不能令人满意。事实上,PHP并不是公司级应用程序的最合适选择,因为它只是关注Web的发展。 PHP是一个很容易抄袭的语言。许多的初学者能立即使用数据库功能创作一个简单Web应用程序,而不用花时间去学习那些像HTML,HTTP,SQL,关系数据库和对象向导等等这样基础的必需的规范。这样无知的做法将导致你只有很糟糕的技术,这也将会导致你很难战胜后来的那些问题和失败所带给你的痛苦。 从C语言这样如此变通的语言遗传来的一些东西,使PHP能产生不同的编程风格,于此不同的是一些像Python这样死板的语言。 事实上的问题是,开发者想方设法使用来自不同源的,并且与自己最初的代码相比是组织好了的完整的代码。 系统管理员可以使用系统中的很多参数对PHP配置进行管理,可以通过在php.ini中设置适当的参数来改变解析器的行为。一些管理员可以熟练的操作项目,但是有一些管理员不行,这就是为什么成型的配置会损害可移植性。让我们把"short_open_tag"参数作为例子来考虑一下。如果它是开启的,那么PHP脚本的开始标签就不仅能使用"<?php"作为主要的标准符号,而且也能使用像在XML里一样的"<?"。当应用程序中既使用XML又使用了PHP时,这可不是个好主意,因此大部分服务器上都将这个功能设置为禁用了。在这样的服务器上还有一些使用了短标签的应用程序不能正确的定位到运行。甚至在PHP官方的文件中,包括在每个发行版中,都标注着:"为了便于移植,重新分配代码,请确定没有使用短标签。"那么,主要做是为什么呢? 2. 命名规则和函数库兼容性。PHP的命名规则看起来和Java有些相似,直到了解了令人厌烦的小写和大写字母的用法才知道这是不一样的。PHP的变量和函数名必须使用小写字母开头,类名必须使用大写字母开头,常数名必须由完整的大写字母组成。在PHP中是很愚蠢的一条就是:变量名是区分大小写的,但是函数名是对大小写不敏感的。没有合理的理由可以解释这是为什么。这会很容易的出现一些很严重的漏洞,例子如下所示: <?php FoR( $count = 0 ; $count < 5 ; $Count++ ) { EcHo('Hello <br />'); } ?> 关键词"for"和函数名echo是不区分大小写的,因此循环应到一直工作直到结束,而不管其它情况是否发生。变量$count和$Count在解析器看来是完全不同的,因此将会产生死循环,这将会导致客户的浏览器暂停响应。 PHP库的结构还没有充分的发展,并且缺乏兼容性。首先,所有的函数的命名规则都不总是一致的。情况是,不友好的函数在他们的名字中的不同位置有"i"或者"case",例如"strripos()"和"strnatcasecmp()"。在系统中没有明显的强调对不强调,例如:base64_encode( ) vs urlencode( ), 或者strip_tags( ) vs stripslashes( )。 更多关于矛盾的例子可以在变函数的前缀和有序参数中找到。 PHP差不多有4000个函数。 其中的一些函数有着很少见的作用,例如phpinfo( ),而且有一些函数还和其他一个或几个函数都有着相同的功能。换句话说,有很多函数执行者相同的功能,因此程序员必须为实际要求选择更合适的函数。列表1描述了PHP和Perl之间一些有相同功能函数数量的对比,数据来源。事实上是,一个好的观点是PHP提供了非常多的有相似功能的函数,而另一个观点则是程序员对此稍微有些难以理解。 很多的的数据库访问函数(例如:mysql_*type 函数)对于数据库来说不是标准化的。PESR(PHP扩展和应用库)提供了一种DB模式,这是种给出了唯一接口的数据库访问模式,但是这种模式有它自己缺陷,这是一种代码的附加层,会减慢运行速度,产生错误的可能性也会增加。 最后,PHP不能使用空名字,因此函数必须有前缀来指出他们的源,这可不是一个好的解决方式。此外,更严重的是命名冲突的概率必然会大大增加。 3.差错处理。PHP为程序的文本错误处理提供了"set_error_handler( )"函数,这个函数运行时可以用来定义一个处理错误的方法。处理错误的关键之处是找对方向,而且需要异常操作的支持。除此之外,用一个安全的方法处理错误,在某种特定的情况下执行相应的代码段,这都是很重要的。 直到PHP5发行,异常处理才被引用,因此是不可能和早期版本相兼容的,但是这不是个大问题,因为早期版本缺少对对象向导支持。 PHP中的用户异常可以很容易通过内置的例外类确定,此外异常处理用一种典型的方式被执行,就像在所有会产生异常的语言中做的那样。PHP中异常处理的缺陷是每当代码出现问题时,解析器不能自动的丢弃异常事件。这有两个例子,都是默认为丢弃异常的,例如: ● 用对象构造的代码: ● 使用这种代码所产生的问题,例如L:使用MySQLi类连接MySQL数据库时会产生严重的问题。 在这些事之后,大量的论述被人们抛出,但是直到PHP6发行,情况也没有任何改变。PHP中存在大量的缺陷的确是个事实,例如:和老版本不相容,代码的可读性很差,但是毕竟它的优点要大于它的缺陷,因此它依然是做Web程序设计的首选。 4.PHP中缺少函数。PHP提供了各种功能的函数用来在现代化的平台上来建立Web应用程序。但是,PHP中仍然缺少一些基本的函数,而且大多是缺少像事件和多线程函数这样重要的函数。 4.1.事件。PHP一个很严重的缺陷是缺少事件。事件允许程序员给对象附上新的行为。 当遇到某些条件时,事件允许程序员灵活的给对象附上新的行为。这些条件是作为一个事件向外部声明的。对象向导语言支持的事件稍微有一些不同。他们其中的一些使用简单的方法,像Javascript或者VB.net,其他的则是定位到高级层次的。总之,建立一个构架来模仿事件也是可行的。 事件的本义包含了对象的实例化以及附加上的事件处理器。当事件联系被提升时,事件处理器将被执行。因此在PHP中支持事件的基本结构需要被建立,这个当前事件必须包含一个类,一个事件的集合,一个事件的处理,一个事件处理的集合,一个允许的事件的类,有意的使用事件。 如果在PHP中能找到支持用户自定义的事件是多么好的一件事情。 4.2.多线程操作。大部分有代表性的Web服务器都使用的多线程的多核CPU。合理的配件价格使得小公司趋向于使用多核的Web服务器。多线程是一种允许应用程序更有效的利用他们新特性的方法。这在复杂的逻辑项目开发工作中也是一个必须的工具。 PHP不支持多线程,这将在不久的将来成为PHP平台主要的缺陷。事实上,在PHP的功能函数中也有几种多线程操作,但是这是很有限的,而且都是很孤立的。当然,多线程操作是困难的,必须为它提供好的了解死锁的抽象方法,竞态条件和数据锁。 PHP-Java桥给我们了一个解决方法,就是使用并行的方法多重检索网页数据,以此来代替使用正常的PHP代码按顺序检索网页。 5.PHP5发行之后的平台开发。PHP6的开发应该可以回溯到2005年。大家都知道,开发人员已经做了很多的工作,一些基本的缺陷也被克服了。尽管这样,但是依然还没有官方发布的PHP6,这的确花了太长的时间。 一个主要的原因是在PHP开发团队内部有很多不同的观点。就问题而言,像安全,异常处理和多线程操作都是很麻烦的一些事情。不管怎样,PHP6迟早都是要发行的,但是一些问题仍然没有得到解决。同时,市场情况也变化的非常快,PHP以往普遍的增长已经停止了。SourceForge.net门户主办了上千的项目,快速搜索它的数据库可以显示注册项目之间的比例 这是显而易见的,Java和PHP各自保持着自己的位置,差距稍微有一点缩小,发展最快的平台是.NET平台。当然,大量的项目并不是决定性的条件,但是这些数据依然是很有象征性的。 助了国家脆弱性数据库。这是美国政府基于脆弱性管理的标准数据库。对脆弱性问题进行检索,将展示出与之相匹配的记录:PHP-8167,Java-1196,ASP-1196.这并不令人惊讶,大量的与Java有关的问题绝对不会少于其他的语言,但是PHP与其他语言相比有着巨大的领先优势。 意见和今后需要做的工作 如今,PHP也许是Web开发中最流行的平台。它在初学者之间很流行,然而,这将会是一件很让人焦虑的事情。如果主要的脆弱部件--PHP脚本不被调查,损害典型的LAMP服务器就将变得非常容易。事实就是,在PHP应用程序中找出了大量的脆弱性因数,这不仅仅是语言本身的,这也将导致很糟糕的程序设计。这其中的一些示例已经被写出来了,而网络新手来是很容易获得的这些代码的。也许现在是时候使着个语言变得更好了,它已经生了很多有安全隐患和错误的实例了。 PHP在其他方面也是缺乏支持的,这主要是指在Web开发平台的竞争中很必要的一些特性。在这些问题被找出之后,必然会有一场广泛的讨论将继续下去,直到有明确的结果为止。 一些PHP中主要的缺陷已经经过商讨,并被克服了。但是在短时间内,大部分的缺陷会存在着,因为,如果用其他方法,PHP的受欢迎程度必然会受到很大的影响。唯一的方法就是,PHP不仅要摆正自己的位置,而且还要面对即将来临的挑战。
信息发布:广州名易软件有限公司 http://www.myidp.net
|