PHP5 OOP編程之代理與自訂異常(1)

日期:2006-09-28  作者:喜騰小二  來源:PHPChina


一、
DBQuery物件


  現在,我們的DBQuery物件簡單地模仿一個存儲過程—一旦被執行,即返回一個必須進行儲存的結果資源;並且如果妳想使用該結果集上的函式(例如num_rows()或fetch_row())的話,妳必須傳遞MySqlDB物件。那麼,如果由DBQuery物件來實現MySqlDB物件(其設計目的是對一個執行查詢的結果進行操作)實現的函式,效果如何呢?讓我們繼續使用上一篇範例中的程式碼;並且讓我們假定,現在由DBQuery物件管理我們的結果資源。DBQuery類的源碼如清單1所示。

  清單1.使用DBQuery類。

require 'mysql_db.php';
require_once 'query.php';
$db = new MySqlDb;

$db->connect('host', 'username', 'pass');
$db->query('use
content_management_system');
$query = new DBQuery($db);

$query->prepare('SELECT fname,sname FROM users WHERE username=:1S AND
pword=:2S AND expire_time<:3I');
try {

 if($query->execute("visualad", "apron", time()))->num_rows() == 1) {

  echo('Correct Credentials');
 } else {
  echo('Incorrect
Credentials / Session Expired');
 }
} catch (QueryException $e) {

 echo('Error executing query: ' . $e);
}

  上麵修改後的程式碼中我們最感興趣的是,catch陳述式和execute陳述式。

  
execute陳述式不再返回一個結果資源,現在它返回DBQuery物件本身。

  
DBQuery物件現在實現num_rows()函式—我們從DB介麵中已經熟悉。

  
如果查詢執行失敗,它抛出一個QueryException類型的異常。當被轉換成一個字串時,它將返回發生的錯誤的細節資訊。

  為此,妳需要使用代理。事實上,妳在我們的DBQuery物件中已經使用代理了,但是現在將更為深入地使用它來把它與MySqlDB物件緊密繫結。該DBQuery物件已經被使用一個實現DB介麵的物件初始化,並且它已經包含一個成員函式execute—由它調用DB物件的query()方法來執行該查詢。這個DBQuery物件本身並不實際地查詢資料庫,它把這項工作交由DB物件來完成。這就是代理,其實是一個處理序—藉助於這個處理序,透過把訊息發送給另一個實現相同的或類似行為的物件,一個物件可以實現一個特別的行為。

  為此,妳需要修改DBQuery物件以便包括所有的函式—它們操作一個來自DB物件的結果資源。當執行查詢以調用DB物件的相應函式並且返回它的結果時,妳需要使用存儲的結果。下列函式將被新增:

  清單2:使用代理延伸DBQuery類。

class DBQuery
{
 .....

 public function fetch_array()
 {

  if (! is_resource($this->result)) {
   throw new Exception('Query not
executed.');
  }
  return $this->db->fetch_array($this->result);
 }


 public function fetch_row()
 {
  if (!
is_resource($this->result)) {
   throw new Exception('Query not executed.');

  }
  return $this->db->fetch_row($this->result);
 }

 public
function fetch_assoc()
 {
  if (! is_resource($this->result)) {

   throw new Exception('Query not executed.');
  }
  return
$this->db->fetch_assoc($this->result);
 }

 public function
fetch_object()
 {
  if (! is_resource($this->result)) {
   throw new
Exception('Query not executed.');
  }
  return
$this->db->fetch_object($this->result);
 }

 public function
num_rows()
 {
  if (! is_resource($this->result)) {
   throw new
Exception('Query not executed.');
  }
  return
$this->db->num_rows($this->result);
 }
}

  每個函式的實現相當簡單。它首先進行檢查,以確保已經執行查詢,然後把工作代理到DB物件,返回它的結果就好像它是查詢物件本身(稱作是基本資料庫函式)一樣。

  二、
類型提示(Type
Hinting)


  為了使代理能夠工作,我們需要確保DBQuery物件的$db變數是一個實現了DB介麵的物件的實例。類型提示是PHP
5中的一種新特徵,它能夠使妳把函式參數強制轉換成特定類型的物件。在PHP
5之前,唯一的確保函式參數是一個特定物件類型的方法是使用PHP中所提供的類型檢查函式(也即是is_a())。現在,妳可以簡單地強制轉換物件類型—透過在函式參數的前麵加上類型名。妳已經從我們的DBQuery物件中看到了類型提示,這樣可以確保一個實現DB介麵的物件被傳遞到物件構造器中。

public function __construct(DB $db)
{
 $this->db =
$db;
}

  當使用類型提示時,妳不僅可以指定物件類型,還可以指定抽象類和介麵。

<<<返回技術中心

技術文章

站內新聞

我要啦免费统计