随着PHP 对工具的支持越来越广泛,以及面向工具的PHP 库和运用程序大量呈现,PHP 中工具的崛起彷佛是一个自然而然且不可避免的过程。但事实远非如此。
工具原来并非PHP 项目的核心部分。实际上,PHP 的设计职员曾将工具描述为“后来才想起来要加上的部分”。PHP中的工具究竟经历了若何的发展过程呢?
正如我们所知,PHP 最初的原型是Rasmus Lerdorf 利用Perl 开拓的两个小工具。PHP 是Personal Homepage Tools 的缩写,表示“个人主页工具”;而FI 则是Form Interpreter 的缩写,表示“表单阐明器”。它们结合而成的宏命令可以将SQL 发送到数据库、处理表单并进行流程掌握。

在用C 措辞重写后,这些工具被授予了新的名字——PHP/FI 2.0。虽然那个期间的PHP 措辞看似和现在不大相同,但实质上没有太大差异。它支持变量、关联数组和函数,但不支持工具。
语法糖:PHP 3事实上,就算到了PHP 3 的操持阶段,工具也未位列个中。PHP 3 的紧张架构师是Zeev Suraski和Andi Gutmans。PHP 3 完备重写了PHP/FI 2.0,但工具并没被视为须要加入的新语法。
根据Zeev Suraski 的回顾,PHP 对类的支持是后来才加上的(准确地说是1997 年8 月27 日)。那时的类和工具实际上是定义和访问关联数组的其余一种办法。
当然,加入了方法和继续的类比关联数组更加强大,但那时对类的操作仍旧很局限,特殊是无法访问父类中被重写的方法(如果不明白这句话的意思也不必担心,我会在后面阐明)。另一个不敷之处是下面将讲到的,工具在PHP 脚本之间的通报办法并非最佳。
在这个期间,工具只是边缘话题,官方文档也没有着重指出这些内容。PHP 手册只用了一句话和一段代码来先容工具,而且这个例子没有提及继续和属性。
一场悄悄静的革命:PHP 4PHP 4 是PHP 的一个打破性版本,许多核心的改变都发生在这个版本中。Zend 引擎(它的名字由Zeev 中的Ze 和Andi 中的nd 结合而成)的问世为PHP 供应了强大的动力,它是驱动PHP的紧张组件之一。任何你可能会调用的PHP 函数,实际上都是高等扩展层的一部分。它们的名字反响了它们所完成的事情,例如与数据库API 进行交互或是与字符串打交道。在底层,Zend引擎管理内存、委托对其他组件的掌握,并将我们熟知且每天都利用的PHP 语法“翻译”为可实行的字节码。正是由于Zend 引擎,我们才可以利用类等PHP 措辞的核心特性。
从面向工具的角度看,PHP 4 给程序员带来的最大便利是可以重写父类的方法并在子类中访问它们。
然而,紧张的缺陷仍旧存在。将工具赋值给一个变量,然后将它通报给函数或是从函数中返回它,都会创建该工具的一个副本。请思考如下两句赋值语句:
$my_obj = new User('bob');$other = $my_obj;
这会导致有两个User 工具存在,而不是指向同一个User 工具的两条引用。大多数面向工具编程措辞都是引用赋值,而非传值赋值,这意味着我们可以通报和赋值指向工具的句柄,而不用复制这些工具。PHP 这种默认的值通报的行为会导致许多潜在的bug,由于程序员在修正了脚本某处的工具后,会误认为其他引用也会有这些修正。你将在本书中看到,我在许多例子中都掩护了多个指向同一个工具的引用。
幸运的是,还有一种逼迫引用通报的办法,但它须要利用一种看起来很笨的语法。
下面是一个引用赋值的例子:
$other =& $my_obj;// $other 和$my_obj 指向同一个工具
下面是一个引用通报参数的例子:
function setSchool(& $school){ // $school 现在是被通报进来的工具的引用,而不是它的副本}
下面是一个引用返回的例子:
function & getSchool(){ // 返回引用而不是副本 return $this->school;}
只管代码也可以正常事情,但在编码过程中,我们实在很随意马虎忘却加上&符号,这就意味着在面向工具的代码中随意马虎滋长bug。而且这些bug 难以跟踪,由于它们不会导致程序出错,只会导致程序的行为与我们预想的不同。
这时的PHP 手册不仅涵盖了语法,还包括了工具方面的内容,而且面向工具编程逐渐成为主流。工具在PHP 中并不是没有引起辩论(现在仍旧一样),类似“我须要工具吗”的帖子在邮件组的谈论中随处可见。Zend 网站上既有支持面向工具编程的谈论文章,也有持反对见地的文章。只管引用通报的问题和各类争议依然存在,但许多程序员还是在他们的代码中加上了&符号,利用面向工具办法进行开拓。利用PHP 进行面向工具编程逐渐发展起来。Zeev Suraski 在Your Information Source for Enterprise Application Development 上揭橥的文章中谈到了这一点:
PHP 发展史上的最大迁移转变之一便是,只管功能非常有限、存在一堆问题和限定,但PHP 中的面向工具编程仍在发达发展,并成为了PHP 开拓中最盛行的开拓办法。这个趋势是我始料未及的,它使得PHP 处于一种不太空想的状态。最明显的一点便是,PHP中工具的行为与其他面向工具编程措辞中工具的行为不同,它更像是关联数组。
如前面所说,很多网站和文章开始谈论面向工具设计。PHP 的官方软件库PEAR 本身就包含了面向工具编程。虽然有些“事后诸葛亮”,但很随意马虎就能看出,PHP 对面向工具的支持只不过是对无法阻挡的面向工具编程趋势的一种妥协。值得把稳的是,只管面向工具编程出身于20 世纪60 年代,但它直到20 世纪90 年代中期才得以遍及。最为盛行的Java 直到1995 年才发布。作为面向过程的C 措辞的超集,C++是在1979 年被设计开拓出来的。经由漫长的发展,C++直到20 世纪90 年代才取得了真正的飞跃。Perl 5 于1994 年发布,新的变革使得这个曾经面向过程的措辞也开始支持面向工具(虽然有些人认为Perl 对面向工具的支持是后来才想到的)。作为一门小型的面向过程的措辞,PHP 迅速实现了对面向工具的支持,这表明了PHP 对用户需求的切实考虑。
拥抱变革:PHP 5PHP 5 是对工具和面向工具编程的认可。这并不是说工具是PHP 唯一的事情办法。但是工具被认为是开拓企业级系统的强大助力和主要方法,而且PHP 在核心设计上也完备支持工具。
随着PHP 5 中功能的增强,越来越多的大型互联网公司开始采取这门措辞,例如Yahoo!和Facebook 在其平台上广泛利用PHP。PHP 已经成为互联网开拓和互联网企业的标准措辞之一。
工具已经从事后的想法变为了PHP 措辞发展的驱动力。可能个中最主要的改变便是用默认的引用通报的行为替代了工具复制。但这只是一个开始。我们该当去打仗PHP 的更多改进,包括private 和protected 的方法和属性、static 关键字、命名空间、类型提示(现在叫作类型声明)以及非常等。PHP 5 已经发布很永劫光了,在此期间不断有主要的新特性面世。
例如,PHP 5.3 带来了命名空间。命名空间许可我们为类和函数创建一个带名字的浸染域,这样可以减小在引用其他库或是扩展系统时碰着重名的可能性。同时,命名空间还将我们从下面这样丑陋的命名约定中拯救了出来:
class megaquiz_util_Conf{}
这样的类名可以防止不同包之间发生类名冲突,但是也会让代码变得很“别扭”。
我们还会看到PHP 对闭包函数、天生器、trait 以及延迟静态绑定的支持。
迎头追赶:PHP 7但程序员不会因此而知足。对付许多喜好设计模式的程序员来说,PHP 仍旧短缺两个关键特性——标量类型声明和逼迫返回类型。在PHP 5 中,如果须要一个工具、数组或是稍后可回调的代码,我们都可以逼迫指定通报给函数或方法的参数的类型,但我们无法逼迫指定标量值(如整数、字符串和浮点型)的类型,也没有办法声明方法或函数的返回值的类型。
正如你将看到的,面向工具设计常常将方法声明作为一种左券。方法会哀求特定的输入,然后返回给你特定的数据类型。利用PHP 5 时,程序员在很多情形下只能依赖注释、约定和手动类型检讨来坚持这类左券。开拓职员和评论员常常抱怨连连。下面的内容引自《深入PHP:面向工具、模式与实践(第3版)》,现已出新版《深入PHP:面向工具、模式与实践(第5版)》。
目前,PHP 开拓组仍未就“在PHP 中加入带提示的返回类型”给出任何承诺。带提示的返回类型许可我们在方法或函数声明中声明要返回的工具的类型,而且PHP 引擎将来也会支持它。带提示的返回类型可以进一步提高PHP 对设计原则(如“针对接口编程,而不是针对实现编程”等原则)的支持。希望有一天,我能够在本书中加入有关这个特性的内容。
我很高兴地写道,这一天终于到来了!
PHP 7 引入了标量类型声明(也便是之条件到的类型提示)以及返回类型声明。你将看到《深入PHP:面向工具、模式与实践(第5版)》中大量利用了这些新特性。PHP 7 还供应了其他不错的特性,比如匿名类和一些命名空间改进。
推戴和顾虑:关于工具的争辩
工具和面向工具设计引发了两方阵营的激烈争辩。许多精良的程序员没有利用工具也编写出了精良的代码,而PHP 仍将是一个精彩的面向过程的Web 编程平台。
本书会自然而然地倾向面向工具,这种倾向反响了作者对面向工具的前景的意见。本书关注工具和面向工具设计,因此会不可避免地强调面向工具。但要把稳的是,本书绝非提倡“面向工具是通往PHP 编程的唯一康庄大道”。
“开拓职员是否选择将PHP 作为面向工具措辞利用”曾经是一个偏好问题,现在仍旧是这样,开拓职员可以利用函数和全局代码创建可完美运行的系统。一些精良工具(如WordPress)的根本架构仍旧是面向过程的(只管这些工具可能会广泛地利用工具)。然而,不该用和不理解PHP对工具的支持,PHP 程序员的开拓过程将变得越来越困难,尤其是项目所依赖的第三方库可能是面向工具的情形。
不过,我们应该记住Perl 的那句名言:“做一件事有很多方法。”对付小型脚本来说尤其如此,由于迅速编写一个程序并让其运行起来,远比构建一种易于扩展为大型系统的架构(在极限编程领域中,这类项目被称为spike)更加主要。
代码是一种很灵巧的东西,编写代码的窍门在于必须知道观点验证会在何时成为大型项目开拓的基石,并在确定设计方案之前停滞大量编码。既然你现在已经决定采取面向工具办法来应对规模不断增长的项目,希望这本书能够为你构建面向工具的架构供应帮助。