在PHP的论坛中总是听到有人对PHP的OOP支持说三道四的,说这有缺陷,那里不足,但是都拿不出实际的例子。原来说过要和大家说说这事,但是一直很忙,现在算是抽了些时间了,所以把我刚刚做过的一个项目的框架拿出来和大家探讨一下。这个项目99%的代码是用oop方式编写的,感觉PHP对于OOP支持非常好,不是一般的好,是非常的好。有由于项目本身是一个商业项目所以源代码不好公布出来,但是基本框架还是可以说一说的,而且经过简化的例子更容易理解一些。如果你对PHP中的OOP还不太了解,还是就此打住吧,先去看看手册,或者基础读物再来看也不迟,反正这个是贴子没有长腿也跑不了。
长话短说,立刻开始吧。我这里会用到一个简单的例子,只有一个半的功能。一个是向浏览器发送一句"Hello, I can say OOP in PHP world!",另外半个功能是从数据库中进行一个查询然后输出到浏览器,说它是半个功能是因为只是作为一个例子讲讲没有实际的数据库操作。
首先从我的第一个文件index.php 开始介绍吧。我的index.php文件是这样的:
双击代码全选 1
2
3
4
5
6 <SPAN ><?php
include_once ('config.php');
include_once ('class.Application.php');
$app = & new Application();
$app->run();
?>
这个就是全部了,虽然只有4行,但是如果用OOP的方式写这个应该就够了吧。
有一点经验的哥们会发现这里只用到了一个Application 对象,那么一定很想知道这个对象究竟长什么样呢?我们继续看看class.Application.php 这个文件的内部。从以上的代码中我们知道她应该至少包含两个方法——Application()和run()。所以大体上应该长成这样:
双击代码全选 1
2
3
4
5
6
7
8
9 <SPAN ><?php
class Application
{
function Application()
{
function run()
}
}
?>
现在就算知道Application 是什么样,它好像也没有办法完成我们预先设定的功能呀? 所以还要介绍一下如何运行这个程序,在我的结构中所有的页面都是通过index.php和一个action参数进行访问的例如第一个功能应该这样访问index.php?action=HelloPage,而第二个功能则是通过index.php?action=DatabasePage进行访问。这样的结构大家也许并不陌生吧。所以index.php 页面应当知道传进来的 action 参数是什么,也就是说Application对象应当知道 这个action 参数是什么。所以我们需要给Application增加一个方法 getAction()来获得action参数。既然知道action,知道了要做什么,那么方法 run()也就有知道如何去run了。
同时我还可以把(完成功能的)每一个页面作为一个对象来看待,所以我应该至少还需要两个类 :class HelloPage 和 class DatabasePage 。由于这两个对象最终都是向浏览器发送页面所以把他们共同的部分提出来作为他们的父类
class Page
以下是三个类文件的内容
双击代码全选 1
2
3
4
5
6
7
8
9
10
11
12
13 <SPAN >class.Page.php
<?php
class Page
{
function Page()
{ }
function show()
{
//不能直接调用这个方法一定要在子类中去具体实现。
die('You can not use this funciton directly from Page class');
}
}
?>
其中这个show方法应该是所有页面对象都具有的方法,只是在实现上有所不同。
双击代码全选 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 <SPAN >class.HelloPage.php
<?php
require_once (\"class.Page.php\");
class HelloPage extends Page
{
function HelloPage()
{
parent : age();
}
function show()
{
echo \"Hello, I can say OOP in PHP world!\";
}
}
?>;
双击代码全选 1
15 <SPAN >class.DatabasePage.php
<?php
require_once (\"class.Page.php\");
class DatabasePage extends Page
{
function DatabasePage()
{
parent: age();
}
function show()
{
//做一些数据库操作然后将结果显示出来。
}
}
?>;
同时我们还遵守这样的一条规则:action的值和调用的页面类的名称保持一致,例如当action=HelloPage的时候程序就知道需要初始化一个HelloPage的对象,有了这样的规则和以上的几个文件我们就可以将 Application 类改进成这样。