跳轉至內容

PHP 程式設計/特殊方法

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

建構函式

[編輯 | 編輯原始碼]

建構函式是類中的一個特殊方法,在建立物件時呼叫。建構函式的使用方法如下


這是 PHP5 版本

  <?php
  class test {
    public $name;   
    public function __construct ($name) {
        $this->name = $name;
     }
  }
  $testing = new test('Hello');
  echo $testing->name;  // Prints 'Hello'
  ?>

這是等效的 PHP4.x 版本:(注意沒有公共/私有關鍵字,類名是建構函式)

  <?php
  class test {
    var $name;   
    function test ($name) {
        $this->name = $name;
     }
  }
  $testing = new test('Hello');
  echo $testing->name;  // Prints 'Hello'
  ?>

在 PHP5 中,建構函式必須宣告為 public,否則將無法工作。建構函式的名稱在 PHP5 中必須始終為 __construct。類名必須在 PHP5 中用作建構函式。

解構函式

[編輯 | 編輯原始碼]

解構函式用於刪除物件的例項。解構函式在物件的類中宣告,包含在銷燬時要執行的其他程式碼。

   <?php
   class myClass {
     function __construct() {
         print "Constructing new myClass...\n";
         $this->name = "My class";
     }
     function __destruct() {
         print "Destroying " . $this->name . "\n";
     }
   }
   $obj = new myClass();
   ?>

注意,解構函式僅存在於 PHP5 中。

為什麼建構函式和解構函式很棒

[編輯 | 編輯原始碼]

為什麼建構函式和解構函式有用?有時,物件表示複雜的實體,它們使用其他資源或具有其他副作用,即使在您的程式中它們看起來像簡單的變數。在這些情況下,建立物件時可能需要特殊設定;您可以使用建構函式來為您自動執行此操作。此外,在程式結束時釋放這些資源非常重要,這樣它們就不會被多個執行或頁面瀏覽佔用;解構函式可以自動處理,這樣您就不會忘記。

以下是一個使處理 MySQL 資料庫稍微簡單的示例

 <?php
 class db_link {
  private $link;
  public function __construct ($database_name) {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
   $this -> link = $link;
   }
  function query ($sql_query) {
   $result = mysql_query ($sql_query, $this -> link);
   return $result;
   }
  function __destruct() {
   mysql_close ($this -> link);
   }
  }
 $db = new db_link ("MyDB");
 $result = $db->query ("Select * from MyTable");
 ?>

類 "db_link" 使用 3 個函式:建構函式,它會在每次建立新的 "db_link" 物件時自動登入資料庫;"query" 函式,我可以用它從資料庫獲取記錄;解構函式,它會在 PHP 完成我的物件例項時自動關閉資料庫。我可以透過為資料庫編寫特殊的 "open" 和 "close" 函式來執行與建構函式和解構函式相同的操作,但我必須每次都呼叫這些函式。這樣一來,我所要做的就是建立物件並使用它們;它們可以自動開啟和關閉自己。


序列化和反序列化

[編輯 | 編輯原始碼]

在某些情況下,需要將例項化的(建立的)物件儲存為靜態文字,以便在程式執行之間儲存,通常儲存在檔案或資料庫欄位中。可以使用序列化來儲存它,序列化會從物件建立一個字串,然後可以反序列化為一個工作物件,包括工作方法和屬性。

可以使用以下方法序列化物件

 <?php
 class test {
  private $test1;
  public function __construct ($testval) {
   $this->test1=$testval;
   }
  public function get_testval() {
   return $testval;
   }
  }
 $testobject = new test ("Testing serialization...")
 $serialized_testobject = serialize($testobject);
 ?>

$serialized_testobject 是一個字串,可以儲存在檔案或資料庫列中,假設它沒有超過列的大小限制。可以使用以下方法對其進行反序列化

 <?php
 class test {
  private $test1;
  public function __construct ($testval) {
   $this->test1=$testval;
   }
  public function get_testval() {
   return $testval;
   }
  }
 $testobject = unserialize($serialized_testobject);
 echo $testobject->get_testval();
 ?>

注意,test 類需要定義,因為它沒有在序列化字串中定義。以不同的方式定義類可能會在反序列化時導致問題。類必須具有相同的名稱。

然而,某些物件在序列化前後需要執行任務,以確保執行之間的一致性。例如,資料庫連結在序列化時需要銷燬,在反序列化時需要重新建立,否則它們將在稍後失效。物件在使用者定義的 __sleep() 方法期間準備好進行序列化,並在反序列化後使用 __wakeup() 準備好工作,如下所示。

 <?php
 class db_link {
  private $link;
  public function __construct ($database_name) {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
   }
  function query ($sql_query) {
   $result = mysql_query ($sql_query, $link);
   return $result;
   }
  function __destruct() {
   mysql_close ($link);
   }
  function __sleep() {
   mysql_close ($link);
  }
  function __wakeup() {
   $link = mysql_connect ("localhost", "your_user_name", "your_password");
   mysql_select_db ($database_name, $link);
  }
 $db = new db_link ("MyDB")
 $result = $db->query ("Select * from MyTable")
 ?>

這裡,連結在序列化時關閉,在反序列化時重新開啟,因為連結可能不會在儲存在文字檔案中幾個小時後具有相同的網路狀態。在複雜的類中,許多屬性和其他不高度依賴時間的 data 將儲存在序列化字串中,而更多易變的事物(如檔案控制代碼和資料庫連結)將在稍後關閉和重新開啟。存在一個例外:可以快速生成的 large amounts of data 應該在 __sleep() 中被銷燬或至少壓縮,以便它們不會佔用序列化檔案中的空間。例如,包含 2000 個條目長的演算法生成的條目的陣列應該被重新生成。


華夏公益教科書