发信人: jackyz() 
整理人: dalasthunder(2002-07-25 06:02:11), 站内信件
 | 
 
 
PHP中的类 
 原文作者:Rod Kreisler ( [email protected] ) 
 文章翻译:三皮( [email protected] ) 
 ---------------------------------------------------------------------
  jackyz注:
 三皮([email protected]) 是 PHP 方面真正的大虾.他和老虎包子
 ([email protected]) 老米飞刀( [email protected] ) 等人是国内研究 PHP 的
 第一批人.当我们都还没听说 PHP 是什么东东的时候.他们已经用 PHP 
 做出了很多很不错的东东.这是其中的一些.
 [http://www.longkou.net]龙口信息港 李波
 [http://www.szptt.net.cn]深圳之窗 老虎包子,老米飞刀
 ......这些开拓者们让我肃然起敬.
 ---------------------------------------------------------------------
  我觉得自从使用PHP以来最难以理解的概念就是PHP的类。我除了正在学习MySQL
  一些基本知识以外,对于其他的数据库引擎没有经验。此前对于OOP面向对象编
  程我也没有经验,OOP对于我来说也是个新鲜事物,但是通过对其原理以及为何
  如此强大的理解,使我有了一定的我了解如果任何程序都用OOP来实现的话,无
  疑会得到一个强大的程序;但是对我而言,如果我只是认为自己了解了其中的机 
 制,而不把这种理解应用到编程实践,OOP对我来说将始终停留在纸上谈兵的层
  次上。于是,几天前,在利用常规的函数来实现一些功能时,我尝试采用对象来 
 实现,我发现的确这让我的工作更加简单了!于是我将这些经验写出来,希望能 
 够帮助象我一样的人们。 
 
 类说穿了就是一些变量(OOP概念中的成员变量,译者注)和一些操作处理这些变
  量的函数(OOP概念中的成员函数)的集合。它提供了一种在程序中以现实生活的
  形态来思考问题的方法,换句话说,就是描述了一个对象。反之,一个对象或者 
 实例,就是这个类的真正实现。比如说我们要描述一辆自行车:一个合适的自行 
 车类应该含有如下变量:$pedals(脚蹬),$chain(链条),
 $front wheel(前轮),$rear wheel(后轮),$brakes(刹车),
 and $handl_bars(车把)。你可以参考现实生活中对一辆自行车的操作来实现你
  的脚本。比如可以通过向函数Accelerate()传递一个$Braking_Force,并将这
 个变量应用于你所定义的实例的其他变量如$front_wheel, $rear_wheel,也
 可以返回操作的结果,从而实现相应的操作。 
 
 看起来很美,但是这些通过常规的函数和变量不是也能够实现吗?不错,如果你 
 的程序中只有一个自行车的实例,为它单独定义一个类的确意思不大,但是如果 
 你需要很多自行车实例的时候呢?但是你程序中的变量传递流会变得相当复杂, 
 你得时时保证每个自行车实例指定的变量都正确的传递给了不同的函数。但是使 
 用对象大大降低了你所传递的变量的数量,因为对象中的处理函数(所谓的方法
  method,译者著。)自动的认定作用范围就限制在本对象之内,那么它所能够操
 作的对象也就限制在了对象范围内。而且对象的定义可以非常容易的包含到不同 
 的脚本只用,(在得到可重用性的同时)还从而保证了每一个自行车的在不同的 
 脚本中工作方式都是一致的。 
 
 让我们来创建一个实际的类,这个类我几乎用在了我站点的每一个页面中,也许 
 你会从中发现值得参考的东西。 
 
 我不知道你是什么情况,但是对我来说,当我写一个动态Web页面的时候,我最
  痛恨的就是时不时要中断对程序流程的思考,转而思考HTML的合适的表现格式。 
 这样做的结果就是使我最终作出来的页面缺少吸引力,因为我没有那么多的精力 
 去顾及字体、字号、背景、以及文字的颜色。解决方法就是:通过PHP类来实现
  对文本的格式化,从而实现HTML的输出属性定制。 
 
 我把这个类命名为“Style”。其中包含了如下一些对于设置HTML属性至关重要
  成员变量: 
 
 <?php 
   class Style { 
     var $text; 
     var $alink; 
     var $vlink; 
     var $link; 
     var $bgcol; 
     var $face; 
     var $size; 
     var $align; 
     var $valign; 
   } 
 ?> 
 
 我想你已经对于HTML语法相当熟悉了,以上的变量名就是他们在HTML语法中的
 名字。接下来我为类Style创建一个名称为Style的成员函数。 
 
 <?php 
   class Style { 
     function Style ($text= "#000000",$alink= "#AA00AA",
       $vlink= "#AA00AA",$link= "#3333FF",$bgcol= "#999999",
       $face= "Book Antiqua",$size=3,$align= "CENTER",
       $valign= "TOP"){
       
       $this->text=$text; 
       $this->alink=$alink; 
       $this->vlink=$vlink; 
       $this->link=$link; 
       $this->bgcol=$bgcol; 
       $this->face=$face; 
       $this->size=$size; 
       $this->align=$align; 
       $this->valign=$valign; 
     } 
   } 
 ?> 
 
 当你在类中创建一个与类同名的成员函数时,这个函数会在你每次创建一个类
 的实例的时候被执行,该函数称为构造函数。我利用这个机制,来使实现在每
 次创建一个对象的时候,自动的为每个HTML属性变量赋予一个缺省值。 
 
 <?php $Basic = new Style; ?> 
 
 上面的语法"=new ClassName;”就是为类Style声明了一个实例$Basic。 
 
 你可以在声明一个类的实例的同时,通过传递参数的形式为类中的某个变量指
 定不同的值。但是即使你声明只修改其中一个变量,也得通知指定其他成员变
 量的值。从这一点来说,类和常规函数是相同的。比如说你要为Style类中的
 text变量指定一个缺省值以外的值,其他的变量你也要指定一遍。不过这还有
 更简单的方法(实际上这就是通常使用的方法,没有什么新鲜的—译者注),就
 是通过在类中加一个成员函数来改变其中类中某个变量的值: 
 
 <?php 
   Function Set($varname,$value) { 
     $this->$varname=$value; 
   } 
 ?> 
 
 然后,我们通过如下的代码就可实现对一个对象实例中指定变量值的修改。 
 
 <?php $Basic->Set( 'size', '2'); ?> 
 
 你必须使用”->”操作符以声明是一个对象的变量或函数。上面的代码就是告
 诉代码解释器”运行$Basic中的Set()成员函数”。解释器就会知道,$Basic
 就是类Style的一个实例,因为我们此前已经声明过了。同样我们可以通过如
 下代码引用一个实例的变量(如:$Basic->text) 
 
 让我们创建一个表头样式对象,其属性与缺省值有些不同。 
 
 <?php 
   $Theader= new Style; 
   $Theader->Set( 'text', '#0000FF'); 
   $Theader->Set( 'bgcol', '#000000'); 
 ?> 
 
 到在这里,够好了吧?现在我的表格头有了蓝色的文字和黑色的北京。我还想
 要我的表体相对于我的主页而言有些轻灰,文字用黑色的,而表体中的文字要
 小一些,于是我可以: 
 
 <?php 
   $Tbody=new Style; 
   $Tbody->Set( 'bgcol', '#AAAAAA'); 
   $Tbody->Set( 'size',2); 
 ?> 
 
 相当不错,现在我们还能够用他来作什么呢?问得好!我很高兴你会问这个问
 题。我们需要在类中再创建几个成员函数来是Style可以用到任何HTML页面对象
  中。首先我要做的就是,为我的页面设置属性,于是: 
 
 <?php 
   function Body() { 
     PRINT "<BODY BGCOLOR="$this->bgcol" ". 
           "TEXT="$this->text" ". 
           "LINK="$this->link" VLINK="$this->vlink" ". 
           "ALINK="$this->alink"><FONT ". 
           "FACE="$this->face" SIZE=$this->size>n"; 
   } 
 ?> 
 
 上述代码,为我站点中的所有页面设置了整体风格。其中还设计到了一个变量
 ”$this”。我们在类中只用这个变量,解释器会自动将其理解为我们在引用当
  前对象本身的一个成员变量。换句话说,$this变量在应用中与对象名称(如本
 例中的$Basic)是等义的。你应该注意到我们在此所做的的确要比用常规函数来
  实现来得简单。我们可以不用向函数传递变量而在函数中引用这个变量。而通
 常,常规函数是通过几个全程变量数组才能够实现这种机制的。不过需要声明
 的是,所有对象的变量和成员函数的作用域都是在本对象范围以内的。 
 
 试验以下下面的PHP代码(假设你已经包含了Style类,并为其创建了一个实例
 $Basic,然后页面中已经有了<HTML> </HTML>和 <HEAD></HEAD> 标签) 
 
 <?php $Basic->Body(); ?> 
 
 这样我们就可以输出一些东西到页面中了,我们可以采用传统的方法,但我想
 做点不同的….(这个作者故弄玄虚,幽默过头了—译者注)这就是我用的另外
  一个成员函数TextOut: 
 
 <?php 
   function TextOut($message= " ") { 
     PRINT "<FONT FACE="$this->face" ". 
           "SIZE=$this->size COLOR="$this-> ". 
           "text">$messagen"; 
   } 
 ?> 
 
 这个函数需要一个参数$message,$message是你要输出的文字,该函数会以指
 定的属性输出这些文字。我们可以通过如下方法实现: 
 
 <?php 
   $Basic->TextOut( 'This is my test message'); 
   $Tbody->TextOut( ' -- kinda neat, huh?'); 
 ?> 
 
 注意,由于这两个函数中间没有输出回车换行<br>,所以结果将输出到同一行
 上。而我还想要第二部分的字体更小一点,这个我在上面的$Tbody对象中已经
 声明了,这样比较安全,$Tbody与$Basic唯一的不同还有个$bgcol属性,在这
 里没有用到。注意到了程序声明中的” ”吗?这是用来在没有参数传递
 给函数时函数,函数就输出缺省的不间断空格,原因后述。 
 
 到目前为止,我们的工作还没有保存。最后的一个例子说明如何通过一种简单
 的方法,来修改字体的颜色和或大小,即使在一个输出语法的中间,也不需要
 改动整个类。我们加入如下的代码: 
 
 <?php 
   function TDOut ($message= " ",$colspan=1) { 
     PRINT "<TD COLSPAN=$colspan BGCOLOR="$this->bgcol" ". 
           "ALIGN="$this->align" VALIGN="$this->valign">"; 
     $this->TextOut($message); 
     PRINT "</TD>n"; 
   } 
 ?> 
 
 那么,讲解就到此为止!记住我想让我的表格有不同的背景颜色,我可以这样
 实现: 
 
 <TABLE> 
 <TR> 
 <?php 
   $Theader->TDOut( "Name",2); 
   $Theader->TDOut( "Location",3); 
 ?> 
 </TR> 
 <TR> 
 <?php 
   $Theader->TDOut( "Last"); 
   $Theader->TDOut( "First"); 
   $Theader->TDOut( "City"); 
   $Theader->TDOut( "State/Province"); 
   $Theader->TDOut( "Country"); 
 ?> 
 </TR> 
 
 这里,你可以看到colspan参数是如何起作用的,如果没有声明,将会有个缺省
  值1。于是在第一个行“Name”中,合并了2列;Location行合并了3列。第二行, 
 所有的列都被合并成了一个。 
 
 我们通过如下方式来实现表体: 
 
 <TR> 
 <?php 
   $Tbody->TDOut( "Kreisler"); 
   $Tbody->TDOut( "Rod"); 
   $Tbody->TDOut( "Cortlandt"); 
   $Tbody->TDOut( "New York"); 
   $Tbody->TDOut( "USA"); 
 ?> 
 </TR> 
 
 但看起来似乎仍然有些繁琐,我们是否可以节省更多的步骤?那么采用下面的
 函数: 
 
 <?php 
   function TROut($message) { 
     /*And NO comments about fish, please! ;) */ 
     PRINT "<TR>n"; 
     $cells=explode( "|",$message); 
     $iterations=count($cells); 
     $i=0; 
     while ($i<$iterations) { 
       list($message,$span)=explode( ":",$cells[$i]); 
       if (strlen($message)<1) $message= " "; 
       if ($span){ 
         $this->TDOut ($message,$span); 
       }else{ 
         $this->TDOut ($message); 
       } 
       $i++; 
     } 
     PRINT "</TR>n"; 
   } 
 ?> 
 
 WOW!看起来有些繁琐,我们来分解一下: 
 
 第3行根据”|”符号分解一个字符串,并且将分解出来的每个元素都放到数组
 $cell中。第四行取得数组的中数组元素的个数到$iterations;第6行开始一个
  循环处理数组中的每个元素。第7行以”:”作为分隔符分解一个数组元素,将
 其存储到$message和$span中。第8行检查$message是否有值。如果没有就赋一
 个缺省值。第九行检查有没有$span(就是合并不合并单元格,通过$cell数据
 中冒号后还有$span来要确定),如果是这样,第10行调用TDOut函数,传递
 $message和单元格个数参数;如果没有第12行程序单纯输出$message信息
 (TDOut函数就用缺省值1来设置$colspan属性)。最后,我们结束一个表格行
 (通过</tr>)。 
 
 或许你看了还有些糊涂(不糊涂才怪),到底如何传递给TROut参数才能包括所有
  的必要信息?正确地格式就是:
 celldata[:colspan]|celldata[:colspan]|......celldata[:colspan]
 (用|分隔单元格,单元格中数据后跟:号分隔的合并单元格的数目来指定要扩
  展本单元格的个数—译者注。) 
 
 所以,总结一下我们以前所作的工作,表头和表体可以通过下面的调用来完成:  
 
 <TABLE> 
 <? 
 $Theader->TROut( "Name:2|Address:3"); 
 $Theader->TROut( "First|Last|City|State/Province|Country"); 
 $Tbody->TROut( "Rod|Kreisler|Cortlandt|New York|USA"); 
 ?> 
 </TABLE> 
 
 Wow!是不是非常的简单?
 (实际上的确非常简单,但是这个作者写的还不足以让人认识到这一点。也就是
  说给的例子缺乏说服力,我个人就觉得依靠TROut这行代码,输出一个行还不如
  样式表来得简单。作者起码用一个BBS的例子来说明OOP在PHP中的用处才有意
 义。当然了,作为PHP中OOP的入门课程,本文也算生动了,而且各个方面讲得
 也差不多。)。 
 
 如果有单元格中的数据存放在变量中的情况怎么办?只要Join数组就可以了: 
  
 <?php 
 
 $message=join($arry, "|"); 
 $Tbody->TROut($message); 
 
 ?> 
 
 当然,你不能在一个Join中同时输入列扩展的单元格数,但是你可以再用一个。 
 假设你的数组包含6个元素,第3和第4行分别要扩展2个和3个单元格,你可以通
  过如下代码实现将:#扩展格数参数指定到$message中 
 
 $newarray=$arry; 
 $newarray[2]=join(list($newarray[2],"2"),":"); 
 $newarray[4]=join(list($newarray[4],"3"),":"); 
 $message=join($newarray,"|"); 
 $Tbody->TROut($message); 
 
 显然,你可以加入更多的成员函数。如果有人有更好的想法,可以Email给我,
  我会封装更多的代码并发表出来。 
 ---------------------------------------------------------------------
  转载自"龙口信息港/东莱论坛/PHP版"
 原文由"三皮"发表
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.87]
  | 
 
 
 |