跳轉到內容

PHP 程式設計/類

來自華夏公益教科書,開放的書籍,開放的世界

類是由三種稱為成員的項組成的結構,即

  1. 常量;
  2. 稱為“屬性”的變數;
  3. 稱為“方法”的函式。

它們中的每一個都以可見性宣告,可見性可以是顯式的(從“私有”、“保護”和“公共”),也可以是隱式的(即省略宣告,僅允許用於預設值為“公共”的方法)。

物件是類的例項,在其中可以呼叫其類的所有方法(如果有),並可以為其類的成員(如果有)提供新的值,覆蓋預設值。

一個簡單的類可以定義如下

  <?php
  
  /* Start the class */
  class Html {
  
     /*
       Declare a public member named "br" with a default value of "&lt;br /&gt;" (the
       XHTML line break)
     */
     public $br = '&lt;br /&gt;';
  
  
     /*
       Declare a public (by default) method named "printLn" requiring an argument
       named "message"
     */
     function printLn ($message) {
        
        /*
          Echo the "message" argument followed by the value of the "br" member (accessed
          through the use of the "$this" keyword (that represents the current object),
          the "->" operator (used to access members) and the member's name ''without''
          the "$" character.
        */
        echo $message . $this->br;
  
     }
  }
  ?>

但是,僅僅因為你建立了一個類並不意味著你可以使用其中的任何東西。類是一個抽象的實體。它是一種表示“以下是如何建立”的方法Html-型別的物件,以及它們的作用。” 為了使用類的成員,你必須建立一個該類的例項

也就是說,你必須實際建立一個“Html”物件並使用它。

定義完類之後,你將要嘗試它。物件是類的例項。在 PHP 中使用物件如下

<?php
$myPage = new Html; // Creates an instance of the Html class
$myPage->printLn('This is some text'); // Prints "This is some text&lt;br /&gt;"
?>

這段程式碼中的新概念是

  • new 關鍵字 — 用於建立一個新的物件例項,在本例中是類 Html 的一個物件。
  • -> 運算子 — 用於訪問例項化物件的成員或方法,在本例中是方法 printLn()

現在,換行符的表示形式是在類的成員中定義的,這使你能夠更改它。請注意,更改僅會影響一個例項,而不是整個類。以下是一個示例(請注意,“<br>” 是一個 HTML 換行符,“<br />” 是一個 XHTML 換行符)

<?php
$myPage = new Html; // Creates an instance of the Html class
$myOldHtmlPage = new Html; // Creates another instance of the Html class
$myOldHtmlPage->br = "&lt;br&gt;"; // Changes the value of the "br" member of the "$myOldHtmlPage" instance to the old HTML value
$myOldHtmlPage->printLn('This is some text'); // Prints "This is some text&lt;br&gt;", the new value of the member is used
$myPage->printLn('This is some text'); // Prints "This is some text&lt;br /&gt;", the default value of the member is kept
?>

但是,請注意,最好避免修改例項的成員:為了允許例項進行可能的約束驗證,應該改為在類中新增(並在處理例項時使用)“get_br” 和 “set_br” 方法來獲取和設定成員的值,同時允許例項執行測試,並可能拒絕更改。

作用域

[編輯 | 編輯原始碼]

類中項的作用域定義了誰可以呼叫它(對於方法)或讀取/更改它的值(對於屬性)。

作用域定義對於屬性是強制性的,對於方法是可選的,其中“公共”是未指定任何內容時的預設值。

公共項可以在任何地方訪問。

在類中定義的保護項可以被例項化此類或此類的子類的物件訪問。

在類中定義的私有項可以被例項化該類的物件訪問。

它們使用 const 宣告(而不是在過程程式設計中使用 define()),可以選擇性地後面跟著一個預設值

const MY_CONSTANT_1 = 0;

它們可以透過反射檢索

$myClass1::getConstants();

儘管將類屬性宣告為公共會使它們更容易使用,但一般不建議這樣做。如果你決定在類的未來版本中對公共屬性執行任何型別的檢查,或者將其儲存在另一個附加屬性中以用於快取目的,你將無法做到這一點,因為其餘程式碼仍將使用公共屬性而沒有任何檢查。

因此,人們應該更喜歡(除了特殊情況)不允許對屬性進行公共訪問,並提供簡單的“get_foo”和“set_foo”方法來返回或覆蓋它們,從而在需要時保留新增複雜性的可能性。

它們可以透過反射檢索

$myClass1::getProperties();

由於方法提供了物件與外部世界的實際介面,因此大多數方法都應該公開訪問。

更準確地說,任何旨在從外部呼叫的方法都應該是公共的。但是,僅用於內部使用且不是介面一部分的方法不應該是公共的。一個典型的例子是一個物件抽象與資料庫的連線,同時提供一個快取系統。應該存在不同的公共方法來允許與外部世界的互動,但是,例如,將原始 SQL 請求傳送到資料庫的方法不應該是公共的,因為任何呼叫它的外部程式碼都會繞過快取,並可能導致無用的負載或(更糟)資料丟失,因為資料庫的資料可能已過期(如果快取中發生了延遲更改)。

它們可以透過反射檢索

$myClass1::getMethods();

實際應用

[編輯 | 編輯原始碼]

上面的示例沒有說明類和物件的情況。為什麼為了訪問函式而去建立所有這些額外的結構呢?

讓我們舉一個可以顯示這種方法如何有用的例子

<?php
class Html {
   private $source = "";
   public function printLn ($message) {
      echo $this->source .= $message . "&lt;br /&gt;";
   }
   public function show () {
      echo $this->source;
   }
}

$elvis = new Html();
$goth = new Html();

$elvis->printLn("Welcome to my Elvis Fan Page! Uh-huh, uh-huh, uh-huh.");
$goth->printLn("Entree the Goth Poetry Labyrinth of Spoooky Doooommmm...");
$elvis->show(); 
?>

一些需要注意的地方

  • 語句echo $this->source .= $message ."&lt;br /&gt;";首先更改私有屬性的值$source然後列印更改後的值。更改後的值已儲存。
  • 不同的副本$source屬性存在於每個例項中Html類。
  • printLnshow函式引用的是同一個副本$source它被呼叫用於他們的物件。 (當我呼叫$elvisprintLn函式時,它會改變$elvis$source變數和語句$elvis->show();列印改變後的值$source).
  • 使用標準變數和方法,將會有更大的風險將錯誤的內容傳送到錯誤的頁面。這對於我的網站訪客來說可能是極其混亂的。

現在我們開始看到如何使用類和物件來節省時間和麻煩。我們現在可以輕鬆地同時管理兩個潛在的網頁,將正確的內容列印到每個頁面。完成後,我們只需呼叫一個頁面的show函式將該頁面的 html 原始碼傳送到輸出流。

我可以透過向管理類新增變數和函式,為所有物件新增更多功能,並且可以根據需要新增更多物件,只需宣告它們即可。事實上,我的程式越複雜,使用面向物件程式設計來管理一切就越容易。


華夏公益教科書