由于最近准备开发一个项目,而做起来又没有头绪,于是找了篇 PHP项目规划来看看,学学PHP项目规划...

译者序:项目规划是业界比较重视的一个专题,但似乎专门讲PHP项目规划的文章不多。在PHP Freaks上看到这篇文章,虽然写得并不专业,但是在相对中文资源相对缺泛和滞后的PHP领域,还是有一点参考价值的。在翻译时觉得原文的语言组织不太符合中文的阅读习惯,于是就对原文的逻辑进行了一定修改。资源共享,欢迎转载,望注明出处。
原文:http://www.phpfreaks.com/tutorials.php?cmd=view&tutorial_id=135
本Blog的原文存档:http://www.dayanmei.com

  作者序:我所见过的大部分的PHP程序都存在架构和组织混乱的问题,这就说明它们缺乏规划。很多PHP程序员并没有对项目进行足够的考虑就一头栽进了编码工作之中。这是我在3-4个月前写的一篇文章,之后我学到了更多,特别是关于OOP技术的东西。


规划?

  无论我们是在开发大型、中型还是小型的项目,规划是始终是最重要的事情。当我们的水平达到某个层次的时候,我们就可以编写一些程序而无需看着教程或书籍。也许我们懂得用PHP连接数据库,输出运算结果,创建类等等。然而,很多人的水平达到这个阶段的时候就很容易只顾编码而完全忽略了规划。

  尽管即兴编程听上去不错,但如果我们要一个工具帮我们实现流线型的编码作业、简便的升级过程以及轻松的编码工作,规划就是最好的选择。如果我们已经规划好了数据库结构,如果我们对自己的代码已经有了大概的轮廓,如果我们非常清楚自己写的程序是做什么用的,那么,编码工作只不过小菜一碟。多数的书籍或教程中都没有详细地讲解规划过程,因为通常作者已经做好了这个工作。但如果我们要自己来编一个程序,那么对程序的规划就显得尤为重要了。当我们要为程序添加新的功能或特性,以及要开发新版本的时候,就会发现程序的规划和良好的代码结构会是开发过程中最重要的一个环节。

  这篇文章会以一个留言本程序作为示例,但并不会教你如何编写PHP代码,而是教你如何更好的组织和规划你的代码。它会探讨程序特性规划、类的规划、数据库结构、模板、消息提取以及一些基础的编码技术



目录

  首先,请看看这篇文章大概包括了哪方面的内容


规划程序特性
你的程序是做什么用的?
程序各种特性之间的关系如何?
用什么代码来处理这些特性间的关系?
数据库
用哪种数据库?
怎么使用数据库?
什么东西存在数据库内?什么东西存在配置文件内?
规划代码结构
你的程序要用哪些类?
这些类是做什么用的?
如何组织它们?
程序是如何调用这些类的?
什么东西写进类里,什么东西写进过程代码里?

  以上的虽然不是这篇文章的全部内容,但是文章会对这些问题进行探讨。



程序特性规划

  规划程序特性最基本的要求是我们必须知道自己的程序是做什么用的。首先,要对程序基本的特性有一个大概的轮廓,就如这个留言本一样,我们可以列出了以下东西:

  1)显示留言功能;2)发表留言功能;3)管理功能;4)模板功能。

  是如何写出这些特性的?很简单,我参考了其它的留言本,看看它们有什么特性,并大概的做了一个分类。然后再想想有什么类型的特性是它们没有而我们又想添加上去的。但这样做只是粗略地勾画出一些基本的特性而已

  现在,我们需要对这些特性进行补充和扩展,列出我们认为程序必须具备的详细特性。下面我们随便列举一些:


显示留言功能
默认每页显示10条留言,但允许用户自行定制
使用java script实现留言的展开和收缩
支持BB代码
发表留言功能
在每一页加上发表留言的链接
必须填写的信息:呢称、留言
可选填的的信息:电子邮件、网站、IM帐号、地理位置
隐藏表单域:IP地址(用于防止垃圾信息)
管理功能
编辑留言
删除留言
屏蔽IP地址
词语过滤器
基本设置:网站名称,留言本名称,网站URL,数据库主机、名称、用户、密码
留言回复
简单的模板编辑及添加功能
管理员身份验证
模板功能
从数据库或文本文件提取变量值并替换

如果你不想自己写模板,可以使用像Smarty和patTemplate这种现成的模板引擎

  当然,写出了以上列表并不代表我们规划好了这个程序,但是你有没有发现把基本特性列出来以后,编码工作变得简单了?当我们开始写代码的时候,就很清楚地知道要往哪里去,以及各种功能之间的联系了。



编码规划

  现在要开始规划代码了。我们要让程序基于数据库运行吗?如果是的话,用什么数据库?又或者是我们是不是想让程序基于文本数据库?如果是的话,如何实现?还有就是,我们的代码是基于哪种结构的?对于大型的程序开发,我的建议只有三个字:Object Oriented Programming。

  开发大型PHP程序最佳的代码结构就是使用OOP。比方说,我们有一个论坛程序是用OOP开发的。现在程序里有一个类叫做view,在view里有一个方法叫viewThreads(),可以通过接受参数来输出帖子内容。如果现在有一个叫viewforum.php的页面用于每次显示一个特定的帖子,那么我们就可以调用$view->viewThreads()来输出结果了。如果还有一个搜索功能,也要输出帖子的内容,那么我们只需调用viewThreads()这个方法即可。如果没有使用OOP,当我们要改变输出帖子的代码的时候,就必须修改每一个显示帖子的文件,但用了OOP,我们只需修改类代码就行。但使用OOP的真正意途是使代码更容易组织和扩展。

  因为,我们决定用OOP来编程了,至少也要用在这个留言本上。现在的问题就是:我们将会编写哪些类?这些类是用于完成什么工作的?如果我们要使用数据库的话,那么至少需要一个类来处理和数据库的数据交换。还有的就是,我们需要一个留言处理类来处理输出和添加留言,一个管理类来完成管理工作,一个模板类来处理模板。在一些大型项目中,我推荐使用现成的模板类如Smarty和patTemplate等,这样既可以免除很多烦琐的工作又可以在程序里面实现一些强大的功能,最重要的一点就是,你现在在编写的是留言本,而不是模板引擎,所以使用现成的就可以了。

  当我们决定了编写哪些类时,最好就把这些类以及它的方法列出来。下面就是一个例子:


code:
<?php
class Entry {

function Entry() {
//这个方法要定义和初始化全局变量以及要包括数据库处理的类
//注意这个方法名要和类的名字一样,这样当类被调用是,这个方法也会被执行
}

function view($num, $start) {
//这个方法会从数据库的中ID为$start的留言开始读出$num条留言数
}

function post($name, $email, $website, $aim, $yim, $msn, $icq, $title, $post) {
//这个方法将把传输过来的数据写入数据库中
}

}
?>
  显然,要完成这些类还要进行很多的编码工作,虽然具体代码还没填上,但是我们已经有了代码的大概结构了,这样就使后面的编码工作轻松多了。

  这个例子并没有完成全部的规划工作,还要对其它的类做同样的工作。但是,这个例子却告诉了你怎么做。无论是大型的CMS、论坛,还是小型的留言本,这种做法都能使你的代码写得更好。



使编码工作更简单的方法

模板

  在开始编程的时候,千万不可以忽略了模板和模板机制。所有的编码工作都必须紧扣模版,因此不要把它放在最后。我推荐使用Smarty模版引擎,当然patTemplate也不错。但无论你选哪个或者你自己来写,都要把这个工作放在最前面来完成,因为模板是和最终用户关系最密切的一部份。我推荐各位最好创建一个类来负责管理模版,这个类并不是去做模版该做的事,只不过是管理它而已。假如我们用Smarty模版,我们可以这样:


code:
<?php
class Template {

function Template() {
require_once("Smarty.php");
$smarty = new Smarty();
}

function showTpl($tpl) {
$smarty->display($tpl);
}
}
?>

  要完善模版管理,我们还要做更多的工作。但上面的这个类足以让你简单地在第一页引用Smarty的调用和输出代码,而无需一次又一次地编写了。



抽象处理

  什么是抽象处理?我们常听到的是“数据库抽象”,一种可以使你无需修改代码就可以访问众多数据库的技术。但是,所谓的抽象处理还有可以是轻松编码的代词。有这样一种情况:我们需要所有的页面的某部分(如页眉、页脚、变量引用等)内容相同,这时我们可以一次又一次地重写这部份的内容,也可以创建一个包括这些重复内容的页面然后在每一页中引用它。虽然输出页面重复内容时引用公共文件的这种方法在Smarty面前已黯然失色,但是,还是有它另类的用法,特别是在一些大型程序中。

  消息抽象就是抽象应用的一个例子。在这个留言本中,我们需要输出如“留言提交成功”、“请输入呢称”等消息,就可以创建一个消息类来处理它:


code:
<?php
class msg {
function msg($num) {
$start = '<p style="font-color:red">';
$end = '</p>';
$message = $start;
switch($num) {
case 1:
$message .= '帐号名错误';
break;

case 2:
$message .= '错码错误';
break;
}
$message .= $end;
echo $message;
}
}
?>
  如果做了登陆页面,我们就可以这样访问消息类:


code:
<?php
include 'msg.php';
if($pass != "arr") {
$msg = new msg(2);
} elseif($user != 1user1) {
$msg = new msg(1);
}
?>

  显然,对于身份验证,上面这个并不是一个好的例子,但我们可以通过它看到消息抽象的好处。我之所以把这个例子引入文章内,是为了使编程更方便。使用类似的消息抽象机制在需要输出反馈信息的地方,你可以很轻松的通过修改一个文件完成相关的工作。

  不仅如此,如果我们需要添加新的消息,只需加上一个新的case即可,然后在相关的地方调用它,而无需再添加echo语句。如果使用模版的话,我们就不可以像上面那样简单地把消息放在类里,而是当类被调用时,使用事先创建的子模版来显示消息,这种方法在Smarty中只不过是三行代码而已。

  现在你应该清楚上面所说的抽象处理了。

  还有一个经常说重点不要忘记,就是在你的代码中添加适当的缩进。类中的第一个方法,程序中的第一个自定义函数、循环语句和表达式等。除此之外,注释也不能忽略。我们肯定很清楚自己刚写完的代码是做什么的,但是几月之后,可能要对代码进行升级,这时,我们就会发现有注释的代码确实易读很多。

规划!

  看完这篇文章,你应该会知道我一直所强调的就是规划,它使编码变得更简单。如果对项目做了规划工作,那么一切进展都会变得顺利。比如说,如果你特定的功能创建了类,那么调试这些工能将会是一个简单的工作;如果你使用了模版引擎,那么你的代码将会显得更简洁、更易于维护和升级。

  一但确定了你工作的方法,就把这些方法用到每一段代码上。每次我对项目进行规划以及使用了适合的工作方法之后,我都会发现编码质量有了飞跃。也许你不愿意把时间放在规划上,因为它会占用你的时间,但当你要添加新功能、升级程序、修改代码或改变界面的时候,你就会那是一件很痛苦的事情。

  看完本文,如果你对规划产生兴趣的话,可以尝试像上面给出的例子一样列出程序各方面的内容,然后编写一些简单的程序,并且试一下基于OOP编程以及使用Smarty的hidden/shown功能。如果你还不懂OOP编程的话,不用急,可以先看一些教程。

  本文教会了你一些规划项目的基本方法,显然,对项目的规划工作并不只有这些。如果你还想了解数据库的设计,可看看本站的LAMP教程,除此之外,本站还有上面提到的消息抽象的教程。无论如何,规划确实对你的工作有很大的帮助,希望本文对你有帮助。