從零開始攻略PHP(8)——面向對象(下)

8.編寫代碼類

  每個分離的函數可以執行一個明確的任務。任務越簡單,編寫與測試這個函數就越簡單,當然也不要將這個函數分得太小——若將程序分成太多的小個體,讀起來就會很困難。

  使用繼承可以重載操作。我們可以替換成一個大的Display()函數,但是改變整個頁面的顯示方式幾乎是不可能的。將顯示功能分成幾個獨立的任務則更好,這樣我們可以只需重載需要改變的部分。

  如下所示的page類提供了簡單靈活的方法來創建頁面:

<?php
class Page
{// class Page's attributespublic $content;  //頁面的主要內容public $title = "TLA Consulting Pty Ltd";   //頁面的標題public $keywords = "TLA Consulting, Three Letter Abbreviation, some of my best friends are search engines";   //metatags便于搜索引擎對其檢索public $buttons = array("Home"   => "home.php", "Contact"  => "contact.php", "Services" => "services.php", "Site Map" => "map.php");    //使用一個數組來保存按鈕的文本標簽以及該按鈕指向的URL// class Page's operationspublic function __set($name, $value){$this->$name = $value;}   //可以從定義訪問函數來設置和獲得已定義的變量值開始public function Display(){echo "<html>\n<head>\n";$this -> DisplayTitle();$this -> DisplayKeywords();$this -> DisplayStyles();echo "</head>\n<body>\n";$this -> DisplayHeader();$this -> DisplayMenu($this->buttons);echo $this->content;$this -> DisplayFooter();echo "</body>\n</html>\n";}public function DisplayTitle(){echo "<title>".$this->title."</title>";}public function DisplayKeywords(){echo "<meta name=\"keywords\" content=\"".$this->keywords."\"/>";}public function DisplayStyles(){ 
?>   <style>h1 {color:white; font-size:24pt; text-align:center; font-family:arial,sans-serif}.menu {color:white; font-size:12pt; text-align:center; font-family:arial,sans-serif; font-weight:bold}td {    background:black}p {color:black; font-size:12pt; text-align:justify; font-family:arial,sans-serif}p.foot {color:white; font-size:9pt; text-align:center; font-family:arial,sans-serif; font-weight:bold}a:link,a:visited,a:active {color:white}</style>
<?php}public function DisplayHeader(){ 
?>   <table width="100%" cellpadding="12" cellspacing="0" border="0"><tr bgcolor ="black"><td align ="left"><img src = "logo.gif" /></td><td><h1>TLA Consulting Pty Ltd</h1></td><td align ="right"><img src = "logo.gif" /></td></tr></table>
<?php}public function DisplayMenu($buttons){echo "<table width=\"100%\" bgcolor=\"white\" cellpadding=\"4\" cellspacing=\"4\">\n";echo "<tr>\n";//calculate button size$width = 100/count($buttons);while (list($name, $url) = each($buttons)) {$this -> DisplayButton($width, $name, $url, !$this->IsURLCurrentPage($url));}echo "</tr>\n";echo "</table>\n";}public function IsURLCurrentPage($url){if(strpos($_SERVER['PHP_SELF'], $url )==false){return false;}else{return true;}}public function DisplayButton($width,$name,$url,$active = true){if ($active) {echo "<td width = \"".$width."%\"><a href=\"".$url."\"><img src=\"s-logo.gif\" alt=\"".$name."\" border=\"0\" /></a><a href=\"".$url."\"><span class=\"menu\">".$name."</span></a></td>";} else {echo "<td width=\"".$width."%\"><img src=\"side-logo.gif\"><span class=\"menu\">".$name."</span></td>";}  }public function DisplayFooter(){
?>
<table width="100%" bgcolor="black" cellpadding="12" border="0">
<tr>
<td><p class="foot">&copy; TLA Consulting Pty Ltd.</p><p class="foot">Please see our <a href ="">legal information page</a></p>
</td>
</tr>
</table>
<?php}
}
?>

  請注意函數DisplayStyles()、DisplayHeader()和DisplayFooter()需要顯示沒有經過PHP處理的大量靜態HTML。因此,我們簡單地使用了PHP結束標記(?>)、輸入HTML,然后再在函數體內部使用一個PHP打開標記(<?php)。

操作IsURLCurrentPage()將判斷按鈕URL是否指向當前頁。

  這里,我們使用了字符串函數strpos(),它可以查看給定的URL是否包含在服務器設置的變量中。strpos($__SERVER[‘PHP_SELF’], $url)語句將返回一個數字(如果$url中的字符串包含在全局變量$_SERVER[‘PHP_SELF’])或者false(如果沒有包含在全局變量中)。

  首頁使用page類完成生成頁面內容的大部分工作:

<?phprequire("page.inc");$homepage = new Page();$homepage->content ="<p>Welcome to the home of TLA Consulting.Please take some time to get to know us.</p><p>We specialize in serving your business needsand hope to hear from you soon.</p>";$homepage->Display();
?>

  在以上的程序清單中可以看出,如果使用Page類,我們在創建新頁面的時候只要做少量工作。通過這種方法使用類意味著所有頁面都必須很相似。

  如果希望網站的一些地方使用不同的標準頁,只要將page.inc復制到名為page2.inc的新文件里,并做一些改變就可以了。這意味著每一次更新或修改page.inc時,要記得對page2.inc進行同樣的修改。

  一個更好的方法是用繼承來創建新類,新類從Page類里繼承大多數功能,但是必須重載需要修改的部分。

  Services頁面繼承了Page類,但是重載了Display()操作,從而改變了其輸出結果:

<?phprequire ("page.inc");class ServicesPage extends Page{private $row2buttons = array("Re-engineering" => "reengineering.php","Standards Compliance" => "standards.php","Buzzword Compliance" => "buzzword.php","Mission Statements" => "mission.php");public function Display(){echo "<html>\n<head>\n";$this -> DisplayTitle();$this -> DisplayKeywords();$this -> DisplayStyles();echo "</head>\n<body>\n";$this -> DisplayHeader();$this -> DisplayMenu($this->buttons);$this -> DisplayMenu($this->row2buttons);echo $this->content;$this -> DisplayFooter();echo "</body>\n</html>\n";}}$services = new ServicesPage();$services -> content ="<p>At TLA Consulting, we offer a numberof services.  Perhaps the productivity of your employees wouldimprove if we re-engineered your business. Maybe all your businessneeds is a fresh mission statement, or a new batch ofbuzzwords.</p>";$services -> Display();
?>

  通過PHP類創建頁面的好處是顯而易見的,通過用類完成了大部分工作,在創建頁面的時候,我們就可以做更少的工作。在更新頁面的時候,只要簡單地更新類即可。通過繼承,我們還可從最初的類派生出不同版本的類而不會破壞這些優勢。

  不過,用腳本創建網頁要求更多計算機處理器的處理操作,應該盡量使用靜態HTML網頁,或者盡可能緩存腳本輸出,從而減少在服務器上的載入操作。

?

9.PHP面向對象的高級功能

  9.1 使用Pre-Class常量

  可以在不需要初始化該類的情況下使用該類中的常量

class Math {const pi = 3.14159; //定義常量

}echo Math::pi;

  可以通過使用::操作符指定常量所屬的類來訪問Per-Class常量。

  9.2 實現靜態方法

  和Pre-Class常量的思想一樣,可以在未初始化類的情況下直接調用這個方法,不過,在這個靜態方法中,不允許使用?this?關鍵字,因為可能會沒有可以引用的對象。

class Math {static function squared($input) {return $input * $input;}}echo Math::squared(8);

  9.3 檢查類的類型和類型提示

  instanceof?關鍵字允許檢查一個對象的類型。可以檢查一個對象是否是特定類的實例,是否是從某個類繼承過來或者是否實現了某個接口。

  另外,類型檢查等價于?instanceof?的作用。

function check_hint(B $someclass){// ...

}

  以上示例將要求$someclass必須是類B的實例。如果按如下方式傳入了類A的一個實例:

check_hint($a);

  將產生如下所示的致命錯誤:

Fatal error: Argument 1 must be an instance of B

  9.4 延遲靜態綁定

  PHP 5.3版本引入了延遲靜態綁定(late static binding)的概念,該特性允許在一個靜態繼承的上下文對一個被調用類的引用。父類可以使用子類重載的靜態方法。如下所示的是PHP手冊提供的延遲靜態綁定示例:

<?phpclass A{public static function who(){echo __CLASS__;}public static function test(){static::who(); // Here comes Late Static Bindings
}}class B extends A{public static function who(){echo __CLASS__;}}B::test();?>

  通俗的說,就是B通過繼承走的A里的test(),然后通過靜態延遲走的B里重載的who()。

  無論類是否被重載,允許在運行時調用類的引用將為你的類提供更多的功能。

  9.5?克隆對象

  PHP提供了?clone?關鍵字,該關鍵字允許復制一個已有的對象。

$c = clone $b;

  將創建與對象?$b?具有相同類的副本,而且具有相同的屬性值。

  當然,可以自己在類中重新定義?__clone?函數,來控制克隆的過程。

  9.6 使用抽象類

  PHP提供了抽象類。這些類不能被實例化,同樣類方法也沒有實現,只是提供類方法的聲明,沒有具體實現。

abstract operationX($param1, $param2);

  包含抽象方法的任何類自身必須是抽象的。

  抽象方法和抽象類主要用于復雜的類層次關系中,該層次關系需要確保每一個子類都包含并重載了某些特性的方法,這也可以通過接口來實現。

  9.7 使用__call()重載方法

  在PHP中,__call()方法用來實現方法的重載。

<?phpclass overload {public function displayArray($array) {foreach($array as $print) {echo $print;echo "<br />";}}public function displayScalar($scalar) {echo $scalar;echo "<br />";}public function __call($method, $p) {if ($method == "display") {if (is_object($p[0])) {$this->displayObject($p[0]);} else if (is_array($p[0])) {$this->displayArray($p[0]);} else {$this->displayScalar($p[0]);}}}}$ov = new overload;$ov->display(array(1, 2, 3));$ov->display('cat');?>

  __call()方法必須帶有兩個參數。第一個包含了被調用的方法名稱,而第二個參數包含了傳遞給該方法的參數數組。

  使用?__call?方法,不需要實現任何?display()?方法。

  9.8 使用__autoload()方法

  __autoload()函數將在實例化一個還沒有被聲明的類時自動調用。

  __autoload()方法的主要用途是嘗試包含或請求任何用來初始化所需類的文件。

  9.9 實現迭代器和迭代

  可以使用foreach()方法通過循環方式取出一個對象的所有屬性,就像數組方式一樣。

<?phpclass myClass{public $a = "5";public $b = "7";public $c = "9";}$x = new myClass;foreach($x as $attribute){echo $attribute."<br />";}?>

  如果需要一些更加復雜的行為,可以實現一個iterator(迭代器)。要實現一個迭代器,必須將要迭代的類實現IteratorAggregare接口,并且定義一個能夠返回該迭代類實例的getIterator方法。這個類必須實現Iterator接口,該接口提供了一系列必須實現的方法。

  迭代器和迭代的示例基類:

?

<?php
class ObjectIterator implements Iterator {  //迭代器 這個類實現了interator接口private $obj;private $count;private $currentIndex;function __construct($obj){$this->obj = $obj;$this->count = count($this->obj->data);}function rewind(){$this->currentIndex = 0;}function valid(){return $this->currentIndex < $this->count;}function key(){return $this->currentIndex;}function current(){return $this->obj->data[$this->currentIndex];}function next(){$this->currentIndex++;}
}class Object implements IteratorAggregate   //接口
{public $data = array();function __construct($in){$this->data = $in;}function getIterator(){return new ObjectIterator($this);   //返回迭代示例的方法
  }
}$myObject = new Object(array(2, 4, 6, 8, 10));$myIterator = $myObject->getIterator();
for($myIterator->rewind(); $myIterator->valid(); $myIterator->next())
{$key = $myIterator->key();$value = $myIterator->current();echo $key." => ".$value."<br />";
}?>

  ObjectIterator類具有Iterator接口所要求的一系列函數:

    · 構造函數并不是必需的,但是很明顯,它是設置將要迭代的項數和當前數據項鏈接的地方。

    · rewind()函數將內部數據指針設置回數據開始處。

    · valid()函數將判斷數據指針的當前位置是否還存在更多數據。

    · key()函數將返回數據指針的值。

    · value()函數將返回保存在當前數據指針的值。

    · next()函數在數據中移動數據指針的位置。

  像這樣使用Iterator類的原因就是即使潛在的實現發生了變化,數據的接口還是不會發生變化。

  9.10 將類轉換成字符串

  __toString()函數的所有返回內容都將被echo語句打印。

<?php$p = new Printable;echo $p;class Printable{public $testone;public $testtwo;public function __toString(){return(var_export($this, TRUE));}}?>

  var_export()函數打印出了類中的所有屬性值。

  9.11 使用Reflection(反射)API

  PHP的面向對象引擎還包括反射API。反射是通過訪問已有類和對象來找到類和對象的結構和內容的能力。

  顯示關于Page類的信息:

<?phprequire_once("page.inc");$class = new ReflectionClass("Page");echo "<pre>".$class."</pre>";?>

  這里使用了Reflection類的__toString()方法來打印這個數據。注意,<pre>標記位于不同的行上,不要與__toString()方法混淆。

?

整理自《PHP和MySQL Web開發》

?

?

?

轉載于:https://www.cnblogs.com/xulei1992/p/5806422.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271044.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271044.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271044.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vb treeview 展開子節點_C# / VB.NET 在PPT中創建、編輯PPT SmartArt圖形

本文介紹通過C#和http://VB.NET程序代碼來創建和編輯PPT文檔中的SmartArt圖形。文中將分兩個操作示例來演示創建和編輯結果。使用工具&#xff1a;Spire.Presentation for .NET hotfix 5.9.5dll文件引用&#xff1a;方式1&#xff1a;下載包&#xff1b;Spire.Presentation for…

mysql安裝教程8.0.21安裝,Windows系統下MySQL8.0.21安裝教程(圖文詳解)

安裝建議&#xff1a;盡量不要用.exe進行安裝&#xff0c;用壓縮包安裝&#xff0c;對日后的卸載/版本升級更為方便下載地址&#xff1a;https://dev.mysql.com/downloads/mysql/1、點擊上面的下載地址得到zip壓縮包2、解壓到要安裝的目錄我這里是E:\database\mysql8\mysql-8.0…

Java中 a+=b和a=a+b有什么區別?

一&#xff1a;性能方面 aab是加法運算 需要兩次尋找地址而ab是增量運算有寄存器優先時 只有一次地址查找。效率方面后者略高于前者 基于現在計算機的發展可忽略不計。 二&#xff1a;對于不同類型的a,b來說 1:不同類型的兩個變量在進行運算的時候&#xff0c;我們經常說到的…

事務管理:事務的狀態相關知識筆記

1、事務的幾個概念中止事務&#xff1a;事務在執行過程中發生故障&#xff0c;不能執行完成的事務。可以進行事務回滾&#xff0c;保持數據庫的一致性。事務回滾&#xff1a;將中止事務對數據庫的更新操作撤銷稱為事務回滾。已提交事務&#xff1a;成功執行完成的事務稱為已提交…

centos7 時間設置

安裝完成centos7后&#xff0c;雖然時區選擇的是上海&#xff0c;但是最終的時間還是不對&#xff0c;因為沒有開啟自動同步NTP功能&#xff0c;所以需要自動手動設置。 首先輸入timedatectl命令&#xff0c;查看當前機器的時間&#xff1a; Local time: 四 2016-08-25 18:52:5…

mysql符合安可要求嗎,安可是什么意思?演唱太過精彩,粉絲要求返場(再唱一個)...

解答&#xff1a;安可是指再唱一個的意思&#xff0c;最早是源自英語“Encore”&#xff0c;常被用在演唱會上&#xff0c;當最后一輪表演或演唱結束之后&#xff0c;粉絲就會開始大喊“安可”&#xff0c;就是想要再聽一場&#xff0c;這時歌手也會應粉絲的要求返場。安可是什…

事務管理基礎:數據庫的并發控制相關知識筆記

1、并發操作的概念介紹并發操作主要是指在多用戶共享的系統當中&#xff0c;可能存在很多用戶同時對同一個數據進行操作。并發操作會造成丟失更新、不可重復讀、讀臟數據。主要原因是事務的并發操作破壞了事務的隔離性。2、事務調度相關知識事務調度主要有串行調度、并發調度、…

Spring的AOP理解

Spring的AOP理解&#xff1a; OOP面向對象&#xff0c;允許開發者定義縱向的關系&#xff0c;但并適用于定義橫向的關系&#xff0c;導致了大量代碼的重復&#xff0c;而不利于各個模塊的重用。 AOP&#xff0c;一般稱為面向切面&#xff0c;作為面向對象的一種補充&#xff…

PHP 常用框架

1、ThinkPHP 2、Yii2 3、Laravel 4、CodeIgniter 5、CakePHP轉載于:https://www.cnblogs.com/baiqian/p/5808935.html

wpf 如何設置彈出窗口必須關閉才能打開其他軟件_5招教你如何清除C盤除系統外的所有垃圾!都學會了嗎?...

老毛桃winpe 2019-04-24 12:22:54 對于C盤&#xff0c;最讓我們頭疼的問題就是空間不足了&#xff01;雖然知道C盤會存有很多垃圾&#xff0c;但由于C盤也是系統盤&#xff0c;我們只能可望不可及。那么&#xff0c;有什么辦法清除C盤除系統外的所有垃圾嗎&#xff1f;答案是…

事務管理基礎:排它鎖和共享鎖相關知識筆記

1、排它鎖、共享鎖出現的意義數據庫的并發事務對數據庫進行讀寫&#xff0c;可能會破壞事務的隔離性和數據一致性。為了保持事務的隔離性&#xff0c;系統必須對事務之間的相互作用加以控制。最典型的做法就是當一個事務訪問某個數據對象時&#xff0c;其他事務都不能更新該數據…

php對象底層結構,PHP 底層原理之類和對象

對于PHPer來說&#xff0c;OOP是不可或缺的開發思維&#xff0c;但是你對php類和對象的底層實現又了解多少呢&#xff1f;本著知其然且知其所以然的思想&#xff0c;讓我們一起來尋找答案~類的底層實現可看作是之前我們講過的變量、函數等的知識集合。所以想要理解更深入的同學…

程序默認在副屏顯示_聊一款性價比極高的電競顯示器

小米在6月17日開啟了小米顯示器27寸165Hz版本的眾籌&#xff0c;這臺顯示器的分辨率為2560x1440&#xff0c;也就是大家熟悉的小金剛&#xff0c;它與大金剛的最大區別也只是省去了G-Sync功能&#xff0c;而其他方面的參數幾乎是一致的。那么我們今天就來聊聊這款真香的顯示器。…

CocoaPods安裝和使用教程

CocoaPods是什么&#xff1f; 當你開發iOS應用時&#xff0c;會經常使用到很多第三方開源類庫&#xff0c;比如JSONKit&#xff0c;AFNetWorking等等。可能某個類庫又用到其他類庫&#xff0c;所以要使用它&#xff0c;必須得另外下載其他類庫&#xff0c;而其他類庫又用到其他…

事務管理基礎:兩段鎖協議、活鎖、死鎖相關知識整理

1、兩段鎖協議&#xff08;Two-phase Locking Protocol&#xff09; 兩段鎖協議是指對任何數據進行讀寫之前必須對數據進行加鎖&#xff1b;在釋放一個封鎖之后&#xff0c;事務不再申請和獲得任何其他封鎖。兩段鎖協議中兩段的含義&#xff1a;事務分為兩個階段&#xff0c;第…

php 空函數,PHP 中函數 isset(), empty(), is_null() 的區別

PHP 中函數 isset(), empty(), is_null() 的區別,使用 PHP 進行開發的時候&#xff0c;經常會用到 isset(), empty(), is_null() 這幾個函數對數據進行判斷&#xff0c;但是這是哪個函數的具體區別其實沒有很好的掌握。下面我們詳細講解一下&#xff1a;NULL什么是 NULL&#x…

UVa11021

11021 TribblesGRAVITATION, n.“The tendency of all bodies to approach one another with a strengthproportion to the quantity of matter they contain – the quantity ofmatter they contain being ascertained by the strength of their tendencyto approach one anot…

python合法變量類型_Python 變量類型

變量存儲在內存中的值。這就意味著在創建變量時會在內存中開辟一個空間。基于變量的數據類型&#xff0c;解釋器會分配指定內存&#xff0c;并決定什么數據可以被存儲在內存中。因此&#xff0c;變量可以指定不同的數據類型&#xff0c;這些變量可以存儲整數&#xff0c;小數或…

數據庫系統故障相關知識筆記

數據庫系統中可能發生的故障主要包括事務故障、系統故障、介質故障、計算機病毒等。下面給大家簡單整理一下相關的故障知識筆記。1、事務故障事務故障是因為程序執行錯誤而引起的非預期、異常終止的故障。主要有邏輯錯誤、系統錯誤導致事務的執行失敗。邏輯錯誤&#xff1a;比如…