来源:www.cncfan.com | 2006-1-11 | (有1831人读过)
概述
OK,你可能已经听说过面向对象,你认为你已经满脑子都是它了。你所交谈 过的每一个人都说面向对象是开发者的真正出路。你应该怎么去做?对你来说它 里面有些什么?并且用PHP到底能做些什么?
广泛地说,所有上面所说的都是真的,但是我猜如果你对OO(面向对象)不熟 悉,你想要看一个具体的例子----一个理想的什么东西,而且这个例子可以应用 在你自已的页面上。好吧,让我们开始吧。
让我们先看一下我们真正想要处理的。[图1]
基本上,我们有三个信息栏 (F1 Teams(F1车队), Drivers Championship(赛 手冠军) 和 Constructors Championship(车队冠军)).
F1 Teams
相当简单,这是一个信息栏,其中有一个无序的列表。每一项都是到车队网 站的链接。
Drivers Championship(赛手冠军)
这是一个信息栏,显示了在F1赛手优胜记录中当前的点数。在这个信息栏中 没有链接。
Constructors Championship(车队冠军)
象赛手优胜记录栏一样,这是一个信息栏,显示了车队优生记录中当前的点 数。
现在,在你发言之前,我知道你可能不想知道现在F1冠军赛的细节,但是它 的确适合作为一个演示用例。在每天的最后,数据被简单地从数据库中取出(在 这个例子中我使用MySQL ),所以你可以使用你喜欢的任何数据。要点就是这些 栏是"伟大的"门户类型工具,用来显示大量的集中的数据。不管你是不是它们的 爱好者,它们就是这样工作的。
如何创建他们?
我的脑子里有好几种可以创建它们的方法:
将大量的代码放在一个web页面中。如果你只想让信息框显示在一个页面中,这个 方法没什么错,但是一旦你开始拆分到交叉页面时,其上的维护工作就变得乏味 了。 将信息框建成SSI(Server Side Include,服务器方包含)文件。这样做仍然 没有什么问题;那么你可以在任意数量的页面中包括信息框,通过引用包含文件 。 将信息框建成对象。开始时,需要多花点时问去建立,但是它有利于生成可移 值代码(我所说的是代码从站点到站点,不只是页面到页面!)。另外,我们创 建了数据源和信息框布局两个接口,这就意味着我们拥有了对数据和布局更简单 地控制。
你可能已经猜到,我们要使用OO方法。其它的要点是什么呢?
那么,让我们从头开始
建立需求。根据这个练习的目的,我定义需求如下:
*.数据源必须可变及可控的。 *.布局大小必须可变及可控的。 *.颜色必须是可变及可定制的。 *.字体外观必须是可控的。
有很多的方法可以用来满足这些要求,对于后面的两个,使用CSS 可能更容 易,这就是我们要做的。对于前两个,这就是故事的开始:
为了建立这个信息框我们将使用七个独立的文件:
index.phtml mysqldb.obj infobox.obj linkbox.obj resultbox.obj constants.inc main.css
标准
所有的.obj文件都是类定义。对每个类或子类我都使用了一个文件。.phtml 文件是我们将插入信息框的文件。.inc文件是一个一般的SSI文件,并且.css文件 是一个真正的样式表文件。
开发过程
象通常的作法,我们首先定义我们的全局常量,然后我们将转移到我们的数 据模式上面(和数据库),跟着是我们的数据类,然后是信息框类,并且最后, 我们将创建.phtml文件,它将所有东西拼装在一起组成一个可以工作的例子---- 或者至少,这就是此时的计划!
常量
这是一个PHP 文件,我创建它用来定义在整个站点上要用的常量。适当地使 用它,就能从一个地方改变站点的外观,而不是不得不在多个页面中对变量进行 修改。下面是我们的constants.inc例子的内容:
<?php
// 数据库常量 $HOST="localhost"; $DB="testing"; $WEBUSER="rOOt"; $WEBPASSWORD="";
// 颜色常量 $COLOR_PRIMARY="#037B0B"; $COLOR_SECONDARY="#FFFFC0"; $COLOR_TERTIARY="#ECED81";
// 常量值 $TRUE=1; $FALSE=0;
// 应用特别设置 $TITLE="Object Orientation Demonstration"; $ADMINEMAIL="webmaster@domin.com";
// CSS插件值 $CSSBOXTITLE="boxtitle";
?>
数据库模式
没有具体的环境,这个模式应该是不真实的数据库模式[图2],但是它是为这 个例子的目的工作的:
如你所见,news数据在一个表中,有自已的要求,同时race,driver,team 和points的详细数据放在一些有关联的表中。如果你不理解这个模式,就不必多 说了,在继续深入之前,你应该去读一下关于RDBMS(译者:关系数据库管理系统 )介绍的资料。
mysqldb类
那么,现在已经定义了RDBMS,并且知道了数据存储在什么地方。是该"玩"面 向对象的时候了!!!
如果你玩PHP 已经有一段时间了,你应该相当清楚有很多可用的函数用来同 许多的数据库进行交互。从根本上说,这个类将作为一些MySQL 函数的包装---- 当然,如果你正在使用Postgres编程(或Oracle,或其它的RDBMS)你可以根据这 些进行修改。
代码如下:
<?php
class mysqldb {
//建立对象 var $host; var $db; var $dbuser; var $dbpassword; var $sql; var $numberrows; var $dbopenstatus; var $dbconnection; /* 使用这些函数得到或设置这个对象的变量的值。 这是好的OO习惯,因为 它意味着数据类型检查可以被完成并且引发相应的错误。 */
// Get和Set属性
function gethost() { return $this->dbhost; } function sethost($req_host) { $this->dbhost = $req_host; } function getdb() { return $this->db; } function setdb($req_db) { $this->db = $req_db; } function getdbuser() { return $this->dbuser; } function setdbuser($req_user) { $this->dbuser = $req_user; } function getdbpassword() { return $this->dbpassword; } function setdbpassword($req_password) { $this->dbpassword = $req_password; } function getsql() { return $this->sql; } function setsql($req_sql) { $this->sql = $req_sql; } function getnumberrows() { return $this->numberrows; } function setnumberrows($req_numberresults) { $this->numberesults = $req_numberresults; } function setdbconnection($req_dbconnection) { $this->dbconnection = $req_connection; } function getdbconnection() { return $this->dbconnection; } /* 这是对象的构造函数。在这个例子中我设置了对象属性的大部分值,使用了在 constants.inc中定义的全局变量的值。通过这样做,对于特别的操作我只需 要改变这些属性的值,这样我们就不需要处理整个例子了。 */ function mysqldb() { global $HOST, $DB, $WEBUSER, $WEBPASSWORD; global $TRUE, $FALSE; $this->sethost($HOST); $this->setdb($DB); $this->setdbuser($WEBUSER); $this->setdbpassword($WEBPASSWORD); $this->setdbconnection($FALSE); } /* 这些是对象的方法。它们提供了打开一个数据库连接,关闭一个连接和执行一个
SELECT查询的功能。当然,这些可以被扩展,以便允许Insert,Update和Delete
等等。 */ function opendbconnection() {
global $TRUE, $FALSE; $this->dbconnection = mysql_connect( "$this->dbhost", "$this- >dbuser", "$this->dbuserpassword"); if ($this->dbconnection == $TRUE) { $this->db = mysql_select_db( "$this->db"); $this->setdbconnection($TRUE); } else { $this->setdbconnection($FALSE); return false; } return true; } function closedbconnection() {
if ($this->dbconnection = $TRUE) { mysql_close($this->dbconnection); } } function selectquery() { global $TRUE, $FALSE; if ($this->dbconnection == $FALSE) { $this->opendbconnection(); } $this->qry = mysql_query($this->sql); if (!$this->qry) { return false; } else { $this->numberrows = mysql_num_rows($this->qry); if ($this->numberrows > 0) { for($x = 0; $x > $this->numberrows; $x++) { $this->result[$x] = mysql_fetch_row($this->qry);
} } else { echo( "[Error:] Retrieving data"); return false; } return true; } } } ?>
上面就是数据类。现在我们需要建立处理实际布局(信息栏)的类!
通用信息类
在这一部分,我们将要创建三个类。不错,是三个类。一个用于管理数据, 两个子类用于绘制信息栏。先从管理数据类开始(把它叫做genericinfo)。这是 代码:
<?php
class genericinfo {
//创建对象,为变量保留内存空间
var $outerwidth; var $outerbordercolor; var $outerborderwidth; var $titlebgcolor; var $innerwidth; var $innerbgcolor;
// 文本的变量 var $title;
// 样式变量 var $cssboxtitle;
/* 使用这些函数,用来得到或设置这个对象变量的值。这是好的OO习惯,因为 它意 味着数据类型检查可以被完成并且引发相应的错误。 */ function setouterwidth($req_outerwidth) { $this->outerwidth = $req_outerwidth; } function getouterwidth() { return $this->getouterwidth; } function setouterbordercolor($req_outerbordercolor) { $this->outerbordercolor = $req_outerbordercolor; } function getouterbordercolor() { return $this->outerbordercolor; } function setouterborderwidth($req_outerborderwidth) { $this->outerborderwidth = $req_outerborderwidth; } function getouterborderwidth() { return $this->outerborderwidth; } function settitlebgcolor($req_titlebgcolor) { $this->titlebgcolor = $req_titlebgcolor; } function gettitlebgcolor() { return $this->titlebgcolor; } function setinnerwidth($req_innerwidth) { $this->innerwidth = $req_innerwidth; } function getinnerwidth() { return $this->innerwidth; } function setinnerbgcolor($req_innerbgcolor) { $this->innerbgcolor = $req_innerbgcolor; } function getinnerbgcolor() { return $this->innerbgcolor; } function settitle($req_title) { $this->title = $req_title; } function gettitle() { return $this->title; } function setcssboxtitle($req_cssboxtitle) { $this->cssboxtitle = $req_cssboxtitle; } function getcssboxtitle() { return $this->cssboxtitle; } /* 这是对象的构造函数。在这个例子中我设置了对象属性的大部分值,使 用了在 constants.inc中定义的全局变量的值。通过这样做,对于特别的操作我 只需 要改变这些属性的值,这样我们就不需要处理整个例子了。 */ function genericinfo() { global $COLOR_PRIMARY, $COLOR_SECONDARY, $COLOR_TERTIARY; global $CSSBOXTITLE; $this->setouterwidth(150); $this->setouterbordercolor($COLOR_TERTIARY); $this->setouterborderwidth(1); $this->settitlebgcolor($COLOR_PRIMARY); $this->setinnerwidth(146); $this->setinnerbgcolor($COLOR_SECONDARY); if (isset($CSSBOXTITLE)) { $this->setcssboxtitle($CSSBOXTITLE); } } // 方法 }
?>
|