免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 62600 | 回复: 86
打印 上一主题 下一主题

[心得 对象] OOP的PHP长啥样 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-12-17 11:51 |只看该作者 |倒序浏览
在PHP的论坛中总是听到有人对PHP的OOP支持说三道四的,说这有缺陷,那里不足,但是都拿不出实际的例子。原来说过要和大家说说这事,但是一直很忙,现在算是抽了些时间了,所以把我刚刚做过的一个项目的框架拿出来和大家探讨一下。这个项目99%的代码是用oop方式编写的,感觉PHP对于OOP支持非常好,不是一般的好,是非常的好。有由于项目本身是一个商业项目所以源代码不好公布出来,但是基本框架还是可以说一说的,而且经过简化的例子更容易理解一些。如果你对PHP中的OOP还不太了解,还是就此打住吧,先去看看手册,或者基础读物再来看也不迟,反正这个是贴子没有长腿也跑不了。

长话短说,立刻开始吧。我这里会用到一个简单的例子,只有一个半的功能。一个是向浏览器发送一句"Hello, I can say OOP in PHP world!",另外半个功能是从数据库中进行一个查询然后输出到浏览器,说它是半个功能是因为只是作为一个例子讲讲没有实际的数据库操作。

首先从我的第一个文件index.php 开始介绍吧。我的index.php文件是这样的:

  1. <?php
  2. include_once ('config.php');
  3. include_once ('class.Application.php');
  4. $app = & new Application();
  5. $app->;run();
  6. ?>;
复制代码

这个就是全部了,虽然只有4行,但是如果用OOP的方式写这个应该就够了吧。
有一点经验的哥们会发现这里只用到了一个Application 对象,那么一定很想知道这个对象究竟长什么样呢?我们继续看看class.Application.php 这个文件的内部。从以上的代码中我们知道她应该至少包含两个方法
Application()

run()
所以大体上应该长成这样

  1. <?php

  2. class Application
  3. {
  4.         function Application()
  5.         {

  6.         }

  7.         function run()
  8.         {

  9.         }
  10. }

  11. ?>;
复制代码

现在就算知道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
以下是三个类文件的内容

class.Page.php

  1. <?php

  2. class Page
  3. {
  4.         function Page()
  5.         {
  6.        
  7.         }

  8.         function show()
  9.         {
  10.                 //不能直接调用这个方法一定要在子类中去具体实现。
  11.                 die('You can not use this funciton directly from Page class');
  12.         }
  13. }
  14. ?>;
复制代码

其中这个show方法应该是所有页面对象都具有的方法,只是在实现上有所不同。

class.HelloPage.php

  1. <?php
  2. require_once ("class.Page.php");

  3. class HelloPage extends Page
  4. {
  5.         function HelloPage()
  6.         {
  7.                 parent::Page();
  8.         }

  9.         function show()
  10.         {
  11.                 echo "Hello, I can say OOP in PHP world!";
  12.         }
  13. }
  14. ?>;
复制代码


class.DatabasePage.php

  1. <?php
  2. require_once ("class.Page.php");

  3. class DatabasePage extends Page
  4. {
  5.         function DatabasePage()
  6.         {
  7.                 parent::Page();
  8.         }

  9.         function show()
  10.         {
  11.                 //做一些数据库操作然后将结果显示出来。
  12.         }
  13. }
  14. ?>;
复制代码


同时我们还遵守这样的一条规则:action的值和调用的页面类的名称保持一致,例如当action=HelloPage的时候程序就知道需要初始化一个HelloPage的对象,有了这样的规则和以上的几个文件我们就可以将 Application 类改进成这样。

  1. <?php

  2. class Application
  3. {
  4.         function Application()
  5.         {

  6.         }

  7.         function getAction()
  8.         {

  9.         }

  10.         function run()
  11.         {
  12.                 $pageClass = $this->;getAction();
  13.                 include_once ("class.".$pageClass.".php");
  14.                 $page = & new $pageClass();
  15.                 $page->;show();
  16.         }
  17. }

  18. ?>;
复制代码

为什么getAction()空着?因为它太简单了,你自己可以轻松地把它写出来呀。

看到这里,如果你还不太明白,不用急,可以停下来重新再看一遍。

如果全明白了,我们就继续前进。我们还有半个任务没有完成,所以我们需要改进我们的Application和页面类,让它完成数据库操作功能。
进行数据库操作之前首先应当得到一个正确的数据库连接,如果让每个需要数据库连接的页面类去做这样的工作实在是一件非常费时费力的工作,不容易维护管理而且也破坏了oop的设计初衷,进行数据库操作的页面类例如 DatabasePage 只应当完成它份内工作即获得数据。 仔细看看我们的设计不难发现建立数据库连接的工作交给 Application 来做最合适不过了, 所以给Application 增加一个新的成员 $db 并且在初始化的时候将建立的数据库连接赋值给它。


  1. <?php
  2. require_once ("class.Database.php");

  3. class Application
  4. {
  5.         var $db;//数据库对象

  6.         function Application()
  7.         {
  8.                 $this->;db = & new Database(DB_HOST,DB_NAME,DB_LOGIN,DB_PASS);//$db 现在是一个数据库对象了
  9.         }

  10.         function getAction()
  11.         {
  12.                 return $_GET['action']; //简单的实现 getAction;
  13.         }

  14.         funciton & getDatabase()
  15.         {
  16.                 return $this->;db;
  17.         }

  18.         function run()
  19.         {
  20.                 $pageClass = $this->;getAction();
  21.                 include_once ("class.".$pageClass.".php");
  22.                 $page = & new $pageClass($this); //这里是唯一做了手脚的地方,将这个Application对象传给页面对象。
  23.                 $page->;show();
  24.         }
  25. }

  26. ?>;
复制代码

你现在不用太关心这个 Database对象从何而来如何实现,知道它是一个含有数据库连接的对象就可以了,如果用过phplib, ADODB,或者Pear库的就很容易理解。
这个语句:
$this->;db = & new Database(DB_HOST,DB_NAME,DB_LOGIN,DB_PASS);
就是建立一个数据库连接而已。

至于DB_HOST,DB_NAME,DB_LOGIN,DB_PASS 这些都是常量我们在config.php中已经预先设定。

由于数据库操作页面 DatabasePage 需要进行数据库连接所以它也需要一个变量 $db 来保存数据库对象,所以我们需要把DatabasePage改进成这样:

class.DatabasePage.php

  1. <?php
  2. require_once ("class.Page.php");

  3. class DatabasePage extends Page
  4. {
  5.         var $db;

  6.         function DatabasePage(&$app)//将Application对象作为参数接受。
  7.         {
  8.                 parent::Page();
  9.                 $this->;db = $app->;getDatabase();//获得 Application 中的数据库对象。
  10.         }

  11.         function show()
  12.         {
  13.                 $sql = 'SELECT * FROM sale_orders';//简单的一个 SQL 例子。
  14.                 $results = $this->;db->;query($sql);//query 是 Database对象的一个公共的方法,通过它向数据库提交SQL查询。
  15.                 ...;//做一些操作把得到的结果显示出来。
  16.         }
  17. }
  18. ?>;
复制代码

好了,一个半的功能算是完成了,PHP对于OOP支持得也很漂亮吧,结构清晰,维护方便,至于效率嘛,我可没看出来有什么损失,如果你有兴趣可以自己测试一下。用这样的框架可以轻松应对各种需求的变化:增加各种权限控制,分离数据库层,商业逻辑,和表象层,增加远程调用接口统统不成问题,只是这里实在写不完这么多的东西。真不知道谁还会有理由说PHP 中OOP 很烂呢?

另外,需要提醒大家的是传递对象和赋值的时候要使用 & 符号这样可以保证每次引用的是同一个对象。

[ 本帖最后由 HonestQiao 于 2006-5-26 21:14 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2003-12-17 12:03 |只看该作者

OOP的PHP长啥样

其实我一直在想~~能不能模仿ASP.NET那样~~~

比如表格,我们可以设计一个表格的类~~~文本框我们可以生成文本框的类~~然后设计一种方式触发事件~~~就像ASP.NET的客户端控件那样~~
如果能设计出完整的PHP的类,那么我们就可以像在ASP.NET里调用客户端控件那样调用这些类~~~在客户端显示我们需要的内容~~

说白了就是学SERVLET和ASP.NET的那套~~~

论坛徽章:
0
3 [报告]
发表于 2003-12-17 13:20 |只看该作者

OOP的PHP长啥样

php5 的 class 样式

  1. class TClassName{
  2.     private $_PrevateVar="hahah";
  3.     protected $_ProtectedVar="hehehehe";
  4.   
  5.    function __construct(){
  6.     //真正的构造函数
  7.    }

  8.    function __destruct() {
  9.        //真正的释购函数
  10.    }

  11.    

  12.     private function privateFunction(){
  13.          try{
  14.            //抛出异常
  15.            throw new MyExceptionFoo('Hello');
  16.         }catch(MyException $exception) {
  17.           //...............
  18.         }
  19.    }

  20.    public function publicFunction(){
  21.          
  22.    }
  23. }

  24. class TSubClassname extends TClassName{
  25.          private function ().....

  26. }

  27. $obj = $obj->;__clone(); //对象的克隆
  28. ... 很多
复制代码


很多 ,到 http://www.php.net/zend-engine-2.php 看看。
我现在已经开始使用了。

以前常用的类似

return sprintf("aaaaa";
这样的写法在 php5 是严重错误,只能这样
$r = sprintf("fasdfasdf";
return $r;

论坛徽章:
0
4 [报告]
发表于 2003-12-17 16:11 |只看该作者

OOP的PHP长啥样

有些时候用类麻烦一点。

但是看看新办主任的php5类,感觉越来越像c++了,呵呵,高兴啊。

论坛徽章:
0
5 [报告]
发表于 2003-12-17 16:23 |只看该作者

OOP的PHP长啥样

OOP的东东 我也是刚学
觉得PHP越来越向C++靠拢了
支持PHP  支持面向对象

论坛徽章:
0
6 [报告]
发表于 2003-12-17 17:08 |只看该作者

OOP的PHP长啥样

说我吗? 我可一直都没说这观点哦

论坛徽章:
0
7 [报告]
发表于 2003-12-17 21:45 |只看该作者

OOP的PHP长啥样

原帖由 "mikespook" 发表:
其实我一直在想~~能不能模仿ASP.NET那样~~~

比如表格,我们可以设计一个表格的类~~~文本框我们可以生成文本框的类~~然后设计一种方式触发事件~~~就像ASP.NET的客户端控件那样~~
如果能设计出完整的PHP的类,那么..........

我不太懂ASP .net的东西,但是你可以看看这个是不是你希望的,或者可以在这个库的基础上改进成你所希望的呢?
http://phphtmllib.newsblob.com/

[quote]原帖由 "iamyess "]说我吗? 我可一直都没说这观点哦...[/quote 发表:
呵呵~~,你又回来啦。这个贴子只是我的一些经验的总结,没有针对什么人的目的。就事论事,欢迎讨论!

论坛徽章:
0
8 [报告]
发表于 2003-12-17 21:54 |只看该作者

OOP的PHP长啥样

不好意思,我又来砸场子

不错,你是写出了个例子,还是实例  :em11:

但是,但是:

你上面说的

"感觉PHP对于OOP支持非常好,不是一般的好,是非常的好"

有什么实际关系呢?也就是说 这个例子能说明什么呢,说明它对 oop 支持得非常好?比一般过程好在哪?

new class 不等于就是  oop

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
9 [报告]
发表于 2003-12-17 22:41 |只看该作者

OOP的PHP长啥样

想请问iamyess,你心里的OO是什么样子,老实说对OO的误解是如此之多,连我都无法肯定我心中的OO到底是不是真正的OO,愿意看看你的理论以印证之。

论坛徽章:
0
10 [报告]
发表于 2003-12-18 00:19 |只看该作者

OOP的PHP长啥样

[quote]原帖由 "iamyess" 发表:
不好意思,我又来砸场子

不错,你是写出了个例子,还是实例  :em11:

但是,但是:

你上面说的

"感觉PHP对于OOP支持非常好,不是一般的好,是非常的好"

有什么实际关系呢?也就是说 这个例子能说明
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP