PHP 已经成熟


Posted in PHP onDecember 04, 2006

由于 PHP 正在成熟,因此是快速即编即用的脚本编制人员与了解 UML 的面向对象的开发人员“思想达成一致”的时候了。

很少有编程语言能够像 PHP 这样迅速地得到普及。现在广泛宣传的那个关于自己动手做 (DIY) 的脚本编制语言改变 IT 业的故事表明,成功不一定总是来自于系统计划和市场研究。但是现在的实际问题是这种成功如何能够为庞大的 IT 业所接受。Oracle 以及其他几个大的参与者正在关注 PHP 铮铮事实表明,这种语言已经成熟。

直到现在,成功也只是刚刚“出现”。数量不断增长的爱好者已经聚集在 PHP 周围,就象聚集在一个天才神童身边一样。但是既然这个孩子正在长出胡子,并开始以平等的地位与成人交谈,那么早期的拥护者会适应这种变化吗?

PHP 与大部分主要的开放源代码项目一样,是正在成为主流技术的过程中的一种基本现象。PHP 会使那些使它获得名誉的人们失望吗?它会达到庞大的 IT 业的期望吗?

两种编程文化的故事

PHP 的成功吸引了不同背景人士的注意。早期的 Rasmus 的拥护者(如果您能谅解那些在开放源代码圈内不常出现的略以救世者自居的语气)习惯于快速的即编即用的脚本编制方法,他们现在必须对付那些了解 UML、面向对象 (OO) 编程的开发人员,这些开发人员决心使 PHP 与其他现代开发工具并驾齐驱。双方都很了解 Web 开发,都拥有强大的文化。忽略任何一方都是不明智的。

早期的 PHP 类型了解 Web 开发的哪些方面,它擅长做什么,不擅长做什么?它了解很多关于设计的问题。它的风格有时可能会有问题,但可以看出它拥有 HTML 和 CSS 功能,不必说更为流行的多信息互联网应用程序 (RIA) 技术了。它总是那么年轻,却经常出现在 PHP 论坛中。术语“面向对象”对于它可能具有负面的涵义。它的代码很扼要,注重表现而不注重可维护性。

由于采用类型松散的变量和为其 HTML 代码填充 <?php?> 语句,因此 UML 类型将更缺乏吸引力。它将要考虑应用程序体系结构、类级代码重用、团队合作以及源代码管理。它知道,即使复杂度适中的网站首先也是一个应用程序,而设计不良的应用程序会导致工期延误、惹恼客户甚至丢掉工作。

乍一看来,后者似乎更适应于需求越来越多的环境,在这种环境中,Web 开发将会越来越多地受到营销策略和经济因素的驱动。但是我们是否应该把前者看作濒临灭绝的物种?或许不应该这样。如果我们承认 Web 是与台式机系统差别很大的一种媒介 — 更不要说大型机了(还有人记得 3270 吗?),在大型 机环境中产生了占统治地位的开发方法 — 则我们可能会得出结论,毕竟可以从这种成功却相对杂乱的方法中学到很好并且有效的东西。

让我们来回顾实际的问题,以便在其可能发生之前加以克服,并回顾一些实际的工作方法。

弥补文化差距

现在 PHP5 即将把面向对象技术带入到 PHP 世界中。Zend 引擎修改 (ZE2) 正在将对象引入到该语言的核心。不仅新的语言构造鼓励对象编程风格,而且语言的实施也正在适应其他的面向对象环境。例如,不再以缺省方式将对象进行来回的复制,而是通过引用来进行处理。引入了新的关键字(如 final 或 static),它们只与对象概念相关,是对 Java 风格的保留;其他特性(如委托)鼓励使用对象设计模式。(期待在几个月的时间后能够听到大家谈论“原有的 PHP4”。) 这种深刻的变化来自于向当前占优势的编程模型进行无情的革命性转移。无论您喜不喜欢,对象方法都将会流行,因为它已证明自己在提供复杂应用程序方面最有效,无论它们是不是 Web 应用程序。这使得我们别无选择,只能寻找富于想象力的方法来协调两种文化,以便具有设计思想的人与了解体系结构的人能够取长补短。

为此,必须开发(或从其他平台中变换出)各种方法,以便在将其包含在清晰的界限内的同时获得语言的多功能性。这样,编程创造力的“孤岛”就可以存在于强健的体系结构中。

一个明显的事实是,尽管 PHP CMS 或应用程序框架的数量呈爆炸性增长,却没有关于它们的一致意见。经常出现的报怨是,无论您的项目是什么,现有系统都不能完成任务。人们大都开始于对若干系统的评估,而最后经常是从头开发自己的框架。这是为什么?

在台式机系统中,似乎已经由操作系统彻底解决了 GUI 设计问题,与此相反,Web 是个原始视觉设计举足轻重的平台。Web 站点承载商业公司的形像和个性,可能会日益影响其收入。视觉创造力与品牌共同发挥作用,因此必须促进它们的发展。

同时,必须能够将灵活的逻辑编入到应用程序中,以便尽可能改善用户体验,应牢记,用户在 Web 上要比在台式机系统中可能表现的更“菜”。

当设计人员不断对程序员所设计的系统感到失望时,这是个问题,而当开发人员不得不将应用代码强行加入到不完备的门户框架中时,这同样是个问题。最常见的结局就是无法令人满意的折中 — 有些呆板的外观、为了将应用的复杂性限制在某个可管理级别而牺牲了很多可用性。(这种现象并不只限于 PHP 应用程序。)

为了彻底克服这些限制,设计人员和面向对象开发人员必须找到一种不阻碍对方工作的协作方法。最好的方法可能是从了解对方团队如何工作开始。

从技巧到产业

此刻先不要考虑协作问题,让我们观察各自的实际操作。让我们按照 PHP 的历史顺序开始,首先访问一个“增强 html”使用者的商店。

进行交易的工具非常类似于“纯 html”使用者的工具:一些 html 编辑器,具有各种级别舒适特性和项目管理特性,并在某种程度上与 PHP、ASP、JavaScript 以及较次要工具相集成。

让我们花点时间仔细观察一下代码。我们首先会注意到,使用这些不同种类的工具生成的网站非常漂亮。我们在这里不仅指技术,也指天赋。由于摆脱了抽象编程因素的限制,Web 设计人员通过摆弄积极、微妙的情感效果(类似于机敏的装饰人员在真实商店中所营造的效果)营造了令您网站的客户感到安适的视觉环境。

当我们从经过训练的面向对象编程者的角度来看这些代码时,事情却突然变得很糟。代码看上去就象它本身一样:它是一次性的、用完即忘的工作,没有为将来的发展或者为简易的维护作出任何准备。经常这样,的确如此。

那么,这有什么不好吗?它以后是否会成为一个难题,导致放弃部分或整个网站并从头开始重建呢?或许不是。毕竟,真实商店的装修经常定期拆除并重建。因此,就这些橱窗式的网站而言,牛仔风格的 PHP 编程已经够用了。这种语言富含各种有助于实现旨在吸引访问者注意的视觉效果的技巧。这里显然与对象方法无关。

一旦需要某些应用逻辑时,这种观点就发生显著的变化。您是否需要若干表单来收集有关您网站的常客的少量的营销信息?如果您希望这种信息能够很中肯,则最好添加校验代码。如果这样做,您应该确保可以过滤恶意脚本或 SQL 指令侵入式攻击。顺便说一下,既然您正在阅读 OTN 文章,因此您一定熟悉数据库 (DB) 问题。您将要收集的这些信息将会存放在某些数据库表中,而您的 PHP 代码中的 SELECT 语句将反映这种数据库结构。从现在开始,这个网站已经固定在您的业务基础架构中 — 它正在成为成熟的应用程序。

我们暂时不要管其所有的硬编码链接、危险的类型转换以及安全漏洞,接着访问最新的 PHP 面向对象应用程序装配线。对于我们那些具有艺术家风范的 Web 设计人员而言,这种地方可能并不熟悉,甚至可能并不友好。在这里不太看重技巧。Web 开发已经产业化了。要想为这里所接受,您必须熟悉类、继承、数据抽象以及大量的代码封装工具。

团队协作需要规则。必须遵循编程惯例;必须将源文件提交版本管理和源代码管理。文件根据严格的模块化层次进行组织。摒弃了那些有危险的编码技巧 — 尤其是那些耍小聪明的技巧。代码不仅必须易读,而且必须有良好的注释。

这样可能令人厌烦,但却很有效。现在我们正在创建 Web 应用程序:内联网、商业 Web 站点、电子市场、各种应用程序,其中具有缺陷的设计都可能会导致停业。简言之,我们正在克服复杂性。

PHP 面向对象装配线的管理者并没有选择 PHP,因为他们热爱这种语言。他们之所以这样做,是因为它不但能像那些专有的其他语言一样有效地完成工作,而且还是免费的,并且没有任何附加条件。

我们要走向何处?

那么我们将如何利用由那些经过 C++ 和 Java 培训的人们所提供的行业级方法,以完成对早期使用者所使用的多功能语言的专业技术的潜在补充?

PHP5 将会动摇很多习惯,因此这个问题可能为时尚早。有些人将被迫采用一定程度的面向对象方法,而另一些人最终会了解面向对象的所有内容并成为它的信仰者。某些小环境可能会象过去那样良好运行并继续兴盛发展。

让我们来实践一下

现在让我们深入到基础的技术级别,了解如何养成简单的习惯,以及寻找简单而有效的解决方案将会如何帮助我们准备好应对即将来临的变化。大量非常简单的惯例有助于促进编程,并使应用程序准备好进行扩展。

命名惯例(C++ 编程人员的习性)是最容易的方式。如果您已经大量使用了代码库(例如 PEAR),则将其惯例作为自己的惯例可能是个好主意;否则应制定您自己的内部规则。简化的匈牙利批注(根据其匈牙利发明者 Charles Symonyi 而命名)可在松散类型所允许的范围内广泛应用。您还可以使用下划线作为类成员的前缀。另一个有用的习惯是,向那些并不用于从类外部进行调用的方法(属于一个类的函数)附加一个特殊的前缀(例如 impl_)。

无论您采用什么命名惯例,都要尽可能使您的代码明确清楚。这样,经过训练的人员就可能在满屏的 PHP 中发现编程错误,只因为它看上去就有问题,就象肖像上的一个污点。

命名惯例的另一个重要方面是避免名称冲突,使得在大范围中重用代码成为可能。经验告诉我们,程序员在命名编程对象方面并不总是非常富有想像力。很有可能,存在很多的 Page 类,而且也不是没有可能当您要重用两个 Page 类时却发现,它们只是名称相同而用途却迥异。真不够走运的。从长远看来,重命名将会带来维护问题。您最好一开始就避免这个问题。生成 GUID 将会矫枉过正、难看(例如 _16B280C5_EE70_11D1_9066_00C04FD9189D_Page!)并且有悖于 PHP 的精神。

一种简单并可以防止冲突的方法是,通过将类的几个不同方面关联到其名称中(例如 GalleryPage),确保内部类的唯一性;而后,为了消除与您控制范围之外的类发生冲突的各种可能,您可以按 Java 的方式将您拥有的域名的保留版本作为它的前缀 (com_mydomain_GalleryPage)。

要养成的另一个习惯不需要您花费什么,并且当某个应用程序范围的意外变化不可避免时,它可以节省您的工作,这就是将最常用的基本语句封装在一个单独的渠道中。例如,除了调试代码,在整个应用程序中只应该有一个“响应”语句,它应该在某个函数(或单独的类方法)中。如果某个新环境中需要对输出进行预处理或重定向,则您知道应该将所需的几行代码写在哪里,而不必面对那种搜索和编辑大量文件的令人沮丧的情况。

错误处理不必像 C++ 中那样严格 — 在 C++ 中,一个悬空指针 (dangling pointer) 或者缓冲区溢出可能极具破坏性。当没有危及数据完整性时,试着大方地放下架子告诉访问者,尽管某些功能不太完善,但她可以再试试。一个经常被忽视的好帮手是标准的 set_error_handler() 函数。这是另一个 — 这次是基本事件 — 封装到一个集中位置(其中所有代码都专门用于处理这些基本事件)的例子。如果您希望保留所有发生错误的事件日志,以便找出重复发生的问题,则应该在这里完成这项工作。

在我们结束低级编程讨论之前,还有另外一个救命招术。在 PHP5 中,缺省情况下,分配或传递对象引用(引用是对象的句柄,而不是对象本身或对象的副本)。只要我们还需要使用 PHP4,就必须认真注意对象的传递方式。某些微妙之处可能使您心神不宁。例如,以下语句导致 $obj2 成为 $obj1 的副本;这并不奇怪。

$obj2=$obj1;

函数将使用副本并返回副本,除非另有指定 — 我们只得接受这种情况。以下示例导致很多了难以跟踪的错误:

class ObjectKeeper {
    var $_obj; // Whatever object is
    function & get_object() {
        return $this->_obj;
    }
}
//引用可以良好地返回。现在陷阱出现了:
$keeper = new ObjectKeeper();
$obj1 = $keeper->get_object();
$obj1->modify();
$obj2 = $keeper->get_object(); // Ask new reference to same object
if ($obj2->is_modified()) {
    echo 'OK'; // 这将永远不会打印
}

正确的语句应该是:

$obj1=&$keeper->get_object(); // 注意,是“=&”而非“=”

如果没有 =&,则返回的引用所指向的对象的副本被分配给 $obj1,而无论您对您认为正确的引用进行什么操作,也不会影响原始对象的状态。换言之,您的更新将会丢失。

在协调 Web 设计人员与程序员的文化方面,模板可能会大有帮助。它们通常包括布局中所配备的一切(主要是 HTML 代码),而在生成页面时,模板引擎填入所有可变的内容。大部分模板引擎带有高速缓存机制,确保相关的耗费资源的处理只发生在数据源更新要求进行这些处理的时候。

接下来的步骤

论坛:Oracle 上的 PHP

PHP 漫游者指南

开放源代码开发人员中心

Oracle + PHP 疑难解答指南

PHP 脚本编制:随心所欲的代码逐渐流行

Oracle + PHP 使用入门

在 Linux 上安装 Oracle、PHP 和 Apache

模板引擎允许在相当大的程度上将布局和图形分在一端,将商务逻辑分在另一端。最流行的模板引擎可能是 Smarty,它也恰好被集成在很多开放源代码的 CMS 和框架项目中。

最后,必须注意当逻辑超出基本的搜索取代式的替换时,模板引擎倾向于提供编程方言。将来的方法很可能依靠 XSLT 技术,而 PHP5 中的扩展 XML 支持将会因此而改变很多。

最后却是相当重要的一个实践方面:从众所周知的库中重用一流的代码。我们的研究将只限于 PEAR,因为它现在是标准 PHP 发行版本中的一部分。

PEAR 可能目前更接近于真正标准的 PHP 软件组件。严格选择提供者以及严格的质量标准确保了组件与商业级组件一样优秀。版本控制惯例为您提供精确控制,以确定组件的哪个版本适合于您的应用程序。PEAR 提供从表单处理到数据库抽象层 (PEAR::DB) 等一系列丰富的功能,并包括 Web 服务或 WebDAV 支持等高级特性。

不用说,通过熟悉 PEAR 以及类似的 PHP 代码库,您可以节省很多天紧张的研发工作。

PHP5 呼之欲出

PHP 已经使自己成为最大的开放源代码成功的故事之一,与 Linux 和 Apache 齐头并立。尽管尚有不理想之处,但它已经在 IT 界牢牢站稳了脚跟,并且其庞大的基层用户群仍然很喜欢它。

PHP5 可能会促进负担沉重的 Web 应用程序的开发,与数据库进行交互作用的业务逻辑层越来越多地接受 PHP 代码。同时,灵活的编程方法将会越来越多地使用 XML 技术,使 Web 设计人员更容易与开发人员和软件设计人员进行无摩擦的协作。

我们期待看到新一代非常具有吸引力并且非常好用的基于 PHP 的 Web 应用程序。

PHP 相关文章推荐
PHP的分页功能
Mar 21 PHP
PHP 定界符 使用技巧
Jun 14 PHP
php关于array_multisort多维数组排序的使用说明
Jan 04 PHP
PHP学习笔记之三 数据库基本操作
Jan 17 PHP
php 操作调试的方法
Jul 12 PHP
ThinkPHP连接数据库的方式汇总
Dec 05 PHP
Laravel 5 框架入门(一)
Apr 09 PHP
php解析url并得到url中的参数及获取url参数的四种方式
Oct 26 PHP
php版微信公众平台回复中文出现乱码问题的解决方法
Sep 22 PHP
php通过会话控制实现身份验证实例
Oct 18 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
Aug 24 PHP
PHP 选项及相关信息函数库
Dec 04 #PHP
PHP 中的面向对象编程:通向大型 PHP 工程的办法
Dec 03 #PHP
windows xp下安装pear
Dec 02 #PHP
PHP+AJAX实现无刷新注册(带用户名实时检测)
Dec 02 #PHP
php字符串截取问题
Nov 28 #PHP
mysq GBKl乱码
Nov 28 #PHP
php类
Nov 27 #PHP
You might like
php中的登陆login
2007/01/18 PHP
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
thinkphp中空模板与空模块的用法实例
2014/11/26 PHP
php使用pear_smtp发送邮件
2016/04/15 PHP
php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
2017/07/10 PHP
ImageZoom 图片放大镜效果(多功能扩展篇)
2010/04/14 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
论Bootstrap3和Foundation5网格系统的异同
2016/05/16 Javascript
jquery输入数字随机抽奖特效的简单实现代码
2016/06/10 Javascript
JavaScript随机生成颜色的方法
2016/10/15 Javascript
Vue-resource拦截器判断token失效跳转的实例
2017/10/27 Javascript
Vue监听一个数组id是否与另一个数组id相同的方法
2018/09/26 Javascript
微信小程序云函数使用mysql数据库过程详解
2019/08/07 Javascript
微信小程序获取用户信息及手机号(后端TP5.0)
2019/09/12 Javascript
vue-cli和v-charts实现可视化图表过程解析
2019/10/08 Javascript
vue之a-table中实现清空选中的数据
2019/11/07 Javascript
详解vue高级特性
2020/06/09 Javascript
js里面的变量范围分享
2020/07/18 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
python原始套接字编程示例分享
2014/02/21 Python
python基础教程之基本数据类型和变量声明介绍
2014/08/29 Python
python获取代理IP的实例分享
2018/05/07 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
Python使用Numpy模块读取文件并绘制图片
2020/05/13 Python
Python 创建守护进程的示例
2020/09/29 Python
python 求两个向量的顺时针夹角操作
2021/03/04 Python
浅谈h5自定义audio(问题及解决)
2016/08/19 HTML / CSS
瑜伽灵感珠宝:Satya Jewelry
2018/01/06 全球购物
香港通票:Hong Kong Pass
2019/02/26 全球购物
阿迪达斯印尼官方网站:adidas印尼
2020/02/10 全球购物
2015年环保局工作总结
2015/05/22 职场文书
公安纪律作风整顿心得体会
2016/01/23 职场文书
职业生涯规划书之大学四年
2019/08/07 职场文书
在HTML5 localStorage中存储对象的示例代码
2021/04/21 Javascript
mysql对于模糊查询like的一些汇总
2021/05/09 MySQL