明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

PHP中的類

[摘要]PHP中的類 作者:酷熊我覺得自從使用PHP以來最難以理解的概念就是PHP的類。我除了正在學(xué)習(xí)MySQL一些基本知識(shí)以外,對(duì)于其他的數(shù)據(jù)庫(kù)引擎沒有經(jīng)驗(yàn)。此前對(duì)于OOP面向?qū)ο缶幊涛乙矝]有經(jīng)驗(yàn),OOP對(duì)于我來說也是個(gè)新鮮事物,但是通過對(duì)其原理以及為何如此強(qiáng)大的理解,使我有了一定的我了解如果任何程序都...
 PHP中的類
作者:酷熊

我覺得自從使用PHP以來最難以理解的概念就是PHP的類。我除了正在學(xué)習(xí)MySQL一些基本知識(shí)以外,對(duì)于其他的數(shù)據(jù)庫(kù)引擎沒有經(jīng)驗(yàn)。此前對(duì)于OOP面向?qū)ο缶幊涛乙矝]有經(jīng)驗(yàn),OOP對(duì)于我來說也是個(gè)新鮮事物,但是通過對(duì)其原理以及為何如此強(qiáng)大的理解,使我有了一定的我了解如果任何程序都用OOP來實(shí)現(xiàn)的話,無(wú)疑會(huì)得到一個(gè)強(qiáng)大的程序;但是對(duì)我而言,如果我只是認(rèn)為自己了解了其中的機(jī)制,而不把這種理解應(yīng)用到編程實(shí)踐,OOP對(duì)我來說將始終停留在紙上談兵的層次上。于是,幾天前,在利用常規(guī)的函數(shù)來實(shí)現(xiàn)一些功能時(shí),我嘗試采用對(duì)象來實(shí)現(xiàn),我發(fā)現(xiàn)的確這讓我的工作更加簡(jiǎn)單了!于是我將這些經(jīng)驗(yàn)寫出來,希望能夠幫助象我一樣的人們。

類說穿了就是一些變量(OOP概念中的成員變量,譯者注)和一些操作處理這些變量的函數(shù)(OOP概念中的成員函數(shù))的集合。它提供了一種在程序中以現(xiàn)實(shí)生活的形態(tài)來思考問題的方法,換句話說,就是描述了一個(gè)對(duì)象。反之,一個(gè)對(duì)象或者實(shí)例,就是這個(gè)類的真正實(shí)現(xiàn)。比如說我們要描述一輛自行車:一個(gè)合適的自行車類應(yīng)該含有如下變量:$pedals(腳蹬),$chain(鏈條),$front wheel(前輪),$rear wheel(后輪),$brakes(剎車), and $handl_bars(車把)。你可以參考現(xiàn)實(shí)生活中對(duì)一輛自行車的操作來實(shí)現(xiàn)你的腳本。比如可以通過向函數(shù)Accelerate()傳遞一個(gè)$Braking_Force,并將這個(gè)變量應(yīng)用于你所定義的實(shí)例的其他變量如$front_wheel, $rear_wheel,也可以返回操作的結(jié)果,從而實(shí)現(xiàn)相應(yīng)的操作。

看起來很美,但是這些通過常規(guī)的函數(shù)和變量不是也能夠?qū)崿F(xiàn)嗎?不錯(cuò),如果你的程序中只有一個(gè)自行車的實(shí)例,為它單獨(dú)定義一個(gè)類的確意思不大,但是如果你需要很多自行車實(shí)例的時(shí)候呢?但是你程序中的變量傳遞流會(huì)變得相當(dāng)復(fù)雜,你得時(shí)時(shí)保證每個(gè)自行車實(shí)例指定的變量都正確的傳遞給了不同的函數(shù)。但是使用對(duì)象大大降低了你所傳遞的變量的數(shù)量,因?yàn)閷?duì)象中的處理函數(shù)(所謂的方法method,譯者著。)自動(dòng)的認(rèn)定作用范圍就限制在本對(duì)象之內(nèi),那么它所能夠操作的對(duì)象也就限制在了對(duì)象范圍內(nèi)。而且對(duì)象的定義可以非常容易的包含到不同的腳本只用,(在得到可重用性的同時(shí))還從而保證了每一個(gè)自行車的在不同的腳本中工作方式都是一致的。

讓我們來創(chuàng)建一個(gè)實(shí)際的類,這個(gè)類我?guī)缀跤迷诹宋艺军c(diǎn)的每一個(gè)頁(yè)面中,也許你會(huì)從中發(fā)現(xiàn)值得參考的東西。

我不知道你是什么情況,但是對(duì)我來說,當(dāng)我寫一個(gè)動(dòng)態(tài)Web頁(yè)面的時(shí)候,我最痛恨的就是時(shí)不時(shí)要中斷對(duì)程序流程的思考,轉(zhuǎn)而思考HTML的合適的表現(xiàn)格式。這樣做的結(jié)果就是使我最終作出來的頁(yè)面缺少吸引力,因?yàn)槲覜]有那么多的精力去顧及字體、字號(hào)、背景、以及文字的顏色。解決方法就是:通過PHP類來實(shí)現(xiàn)對(duì)文本的格式化,從而實(shí)現(xiàn)HTML的輸出屬性定制。


我把這個(gè)類命名為“Style”。其中包含了如下一些對(duì)于設(shè)置HTML屬性至關(guān)重要成員變量:

<?php

class Style {

var $text;
var $alink;
var $vlink;
var $link;
var $bgcol;
var $face;
var $size;
var $align;
var $valign;

}

?>

我想你已經(jīng)對(duì)于HTML語(yǔ)法相當(dāng)熟悉了,以上的變量名就是他們?cè)贖TML語(yǔ)法中的名字。接下來我為類Style創(chuàng)建一個(gè)名稱為Style的成員函數(shù)。

<?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;

}

}
?>

當(dāng)你在類中創(chuàng)建一個(gè)與類同名的成員函數(shù)時(shí),這個(gè)函數(shù)會(huì)在你每次創(chuàng)建一個(gè)類的實(shí)例的時(shí)候被執(zhí)行,該函數(shù)稱為構(gòu)造函數(shù)。我利用這個(gè)機(jī)制,來使實(shí)現(xiàn)在每次創(chuàng)建一個(gè)對(duì)象的時(shí)候,自動(dòng)的為每個(gè)HTML屬性變量賦予一個(gè)缺省值。

<?php $Basic = new Style; ?>

上面的語(yǔ)法"=new ClassName;”就是為類Style聲明了一個(gè)實(shí)例$Basic。

你可以在聲明一個(gè)類的實(shí)例的同時(shí),通過傳遞參數(shù)的形式為類中的某個(gè)變量指定不同的值。但是即使你聲明只修改其中一個(gè)變量,也得通知指定其他成員變量的值。從這一點(diǎn)來說,類和常規(guī)函數(shù)是相同的。比如說你要為Style類中的text變量指定一個(gè)缺省值以外的值,其他的變量你也要指定一遍。不過這還有更簡(jiǎn)單的方法(實(shí)際上這就是通常使用的方法,沒有什么新鮮的—譯者注),就是通過在類中加一個(gè)成員函數(shù)來改變其中類中某個(gè)變量的值:

<?php

Function Set($varname,$value) {

$this->$varname=$value;

}

?>

然后,我們通過如下的代碼就可實(shí)現(xiàn)對(duì)一個(gè)對(duì)象實(shí)例中指定變量值的修改。

<?php $Basic->Set( 'size', '2'); ?>

你必須使用”->”操作符以聲明是一個(gè)對(duì)象的變量或函數(shù)。上面的代碼就是告訴代碼解釋器”運(yùn)行$Basic中的Set()成員函數(shù)”。解釋器就會(huì)知道,$Basic就是類Style的一個(gè)實(shí)例,因?yàn)槲覀兇饲耙呀?jīng)聲明過了。同樣我們可以通過如下代碼引用一個(gè)實(shí)例的變量(如:$Basic->text)

讓我們創(chuàng)建一個(gè)表頭樣式對(duì)象,其屬性與缺省值有些不同。

<?php

$Theader= new Style;
$Theader->Set( 'text', '#0000FF');
$Theader->Set( 'bgcol', '#000000');

?>

到在這里,夠好了吧?現(xiàn)在我的表格頭有了藍(lán)色的文字和黑色的北京。我還想要我的表體相對(duì)于我的主頁(yè)而言有些輕灰,文字用黑色的,而表體中的文字要小一些,于是我可以:

<?php

$Tbody=new Style;
$Tbody->Set( 'bgcol', '#AAAAAA');
$Tbody->Set( 'size',2);

?>

相當(dāng)不錯(cuò),現(xiàn)在我們還能夠用他來作什么呢?問得好!我很高興你會(huì)問這個(gè)問題。我們需要在類中再創(chuàng)建幾個(gè)成員函數(shù)來是Style可以用到任何HTML頁(yè)面對(duì)象中。首先我要做的就是,為我的頁(yè)面設(shè)置屬性,于是:

<?php

function Body() {

PRINT "<BODY BGCOLOR="$this->bgcol" ".
"TEXT="$this->text" ".
"LINK="$this->link" VLINK="$this->vlink" ".
"ALINK="$this->alink"> ";

}

?>

上述代碼,為我站點(diǎn)中的所有頁(yè)面設(shè)置了整體風(fēng)格。其中還設(shè)計(jì)到了一個(gè)變量”$this”。我們?cè)陬愔兄挥眠@個(gè)變量,解釋器會(huì)自動(dòng)將其理解為我們?cè)谝卯?dāng)前對(duì)象本身的一個(gè)成員變量。換句話說,$this變量在應(yīng)用中與對(duì)象名稱(如本例中的$Basic)是等義的。你應(yīng)該注意到我們?cè)诖怂龅牡拇_要比用常規(guī)函數(shù)來實(shí)現(xiàn)來得簡(jiǎn)單。我們可以不用向函數(shù)傳遞變量而在函數(shù)中引用這個(gè)變量。而通常,常規(guī)函數(shù)是通過幾個(gè)全程變量數(shù)組才能夠?qū)崿F(xiàn)這種機(jī)制的。不過需要聲明的是,所有對(duì)象的變量和成員函數(shù)的作用域都是在本對(duì)象范圍以內(nèi)的。

試驗(yàn)以下下面的PHP代碼(假設(shè)你已經(jīng)包含了Style類,并為其創(chuàng)建了一個(gè)實(shí)例$Basic,然后頁(yè)面中已經(jīng)有了 和 <HEAD></HEAD> 標(biāo)簽)

<?php $Basic->Body(); ?>

這樣我們就可以輸出一些東西到頁(yè)面中了,我們可以采用傳統(tǒng)的方法,但我想做點(diǎn)不同的….(這個(gè)作者故弄玄虛,幽默過頭了—譯者注)這就是我用的另外一個(gè)成員函數(shù)TextOut:

<?php

function TextOut($message= " ") {

PRINT " "text">$message ";

}

?>

這個(gè)函數(shù)需要一個(gè)參數(shù)$message,$message是你要輸出的文字,該函數(shù)會(huì)以指定的屬性輸出這些文字。我們可以通過如下方法實(shí)現(xiàn):

<?php

$Basic->TextOut( 'This is my test message');
$Tbody->TextOut( ' -- kinda neat, huh?');

?>

注意,由于這兩個(gè)函數(shù)中間沒有輸出回車換行<br>,所以結(jié)果將輸出到同一行上。而我還想要第二部分的字體更小一點(diǎn),這個(gè)我在上面的$Tbody對(duì)象中已經(jīng)聲明了,這樣比較安全,$Tbody與$Basic唯一的不同還有個(gè)$bgcol屬性,在這里沒有用到。注意到了程序聲明中的” ”嗎?這是用來在沒有參數(shù)傳遞給函數(shù)時(shí)函數(shù),函數(shù)就輸出缺省的不間斷空格,原因后述。

到目前為止,我們的工作還沒有保存。最后的一個(gè)例子說明如何通過一種簡(jiǎn)單的方法,來修改字體的顏色和或大小,即使在一個(gè)輸出語(yǔ)法的中間,也不需要改動(dòng)整個(gè)類。我們加入如下的代碼:

<?php

function TDOut ($message= " ",$colspan=1) {

PRINT "<TD COLSPAN=$colspan BGCOLOR="$this->bgcol" ".
"ALIGN="$this->align" VALIGN="$this->valign">";
$this->TextOut($message);
PRINT "</TD>
";

}

?>

那么,講解就到此為止!記住我想讓我的表格有不同的背景顏色,我可以這樣實(shí)現(xià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參數(shù)是如何起作用的,如果沒有聲明,將會(huì)有個(gè)缺省值1。于是在第一個(gè)行“Name”中,合并了2列;Location行合并了3列。第二行,所有的列都被合并成了一個(gè)。

我們通過如下方式來實(shí)現(xiàn)表體:

<TR>
<?php

$Tbody->TDOut( "Kreisler");
$Tbody->TDOut( "Rod");
$Tbody->TDOut( "Cortlandt");
$Tbody->TDOut( "New York");
$Tbody->TDOut( "USA");
?>
</TR>

但看起來似乎仍然有些繁瑣,我們是否可以節(jié)省更多的步驟?那么采用下面的函數(shù):

<?php

function TROut($message) { /*And NO comments about fish, please! ;) */

PRINT "<TR>
";
$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>
";

}

?>

WOW!看起來有些繁瑣,我們來分解一下:

第3行根據(jù)” ”符號(hào)分解一個(gè)字符串,并且將分解出來的每個(gè)元素都放到數(shù)組$cell中。第四行取得數(shù)組的中數(shù)組元素的個(gè)數(shù)到$iterations;第6行開始一個(gè)循環(huán)處理數(shù)組中的每個(gè)元素。第7行以”:”作為分隔符分解一個(gè)數(shù)組元素,將其存儲(chǔ)到$message和$span中。第8行檢查$message是否有值。如果沒有就賦一個(gè)缺省值。第九行檢查有沒有$span(就是合并不合并單元格,通過$cell數(shù)據(jù)中冒號(hào)后還有$span來要確定),如果是這樣,第10行調(diào)用TDOut函數(shù),傳遞$message和單元格個(gè)數(shù)參數(shù);如果沒有第12行程序單純輸出$message信息(TDOut函數(shù)就用缺省值1來設(shè)置$colspan屬性)。最后,我們結(jié)束一個(gè)表格行(通過</tr>)。

或許你看了還有些糊涂(不糊涂才怪),到底如何傳遞給TROut參數(shù)才能包括所有的必要信息?正確地格式就是:celldata[:colspan] celldata[:colspan] ......celldata[:colspan](用 分隔單元格,單元格中數(shù)據(jù)后跟:號(hào)分隔的合并單元格的數(shù)目來指定要擴(kuò)展本單元格的個(gè)數(shù)—譯者注。)

所以,總結(jié)一下我們以前所作的工作,表頭和表體可以通過下面的調(diào)用來完成:

<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!是不是非常的簡(jiǎn)單?(實(shí)際上的確非常簡(jiǎn)單,但是這個(gè)作者寫的還不足以讓人認(rèn)識(shí)到這一點(diǎn)。也就是說給的例子缺乏說服力,我個(gè)人就覺得依靠TROut這行代碼,輸出一個(gè)行還不如樣式表來得簡(jiǎn)單。作者起碼用一個(gè)BBS的例子來說明OOP在PHP中的用處才有意義。當(dāng)然了,作為PHP中OOP的入門課程,本文也算生動(dòng)了,而且各個(gè)方面講得也差不多。)。

如果有單元格中的數(shù)據(jù)存放在變量中的情況怎么辦?只要Join數(shù)組就可以了:

<?php

$message=join($arry, " ");
$Tbody->TROut($message);

?>

當(dāng)然,你不能在一個(gè)Join中同時(shí)輸入列擴(kuò)展的單元格數(shù),但是你可以再用一個(gè)。假設(shè)你的數(shù)組包含6個(gè)元素,第3和第4行分別要擴(kuò)展2個(gè)和3個(gè)單元格,你可以通過如下代碼實(shí)現(xiàn)將:#擴(kuò)展格數(shù)參數(shù)指定到$message中

$newarray=$arry;
$newarray[2]=join(list($newarray[2],"2"),":");
$newarray[4]=join(list($newarray[4],"3"),":");
$message=join($newarray," ");
$Tbody->TROut($message);

顯然,你可以加入更多的成員函數(shù)。如果有人有更好的想法,可以Email給我,我會(huì)封裝更多的代碼并發(fā)表出來。




標(biāo)簽:PHP中的類