Heim > php教程 > php手册 > PHP5 OOP编程中的代理与异常定制

PHP5 OOP编程中的代理与异常定制

WBOY
Freigeben: 2016-06-13 10:33:15
Original
855 Leute haben es durchsucht

一、 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;
}

  当使用类型提示时,你不仅可以指定对象类型,还可以指定抽象类和接口。

  三、 抛出异常

  你可能已经从上面的代码中注意到,你捕获的是一个称为QueryException(我们将在后面实现这个对象)的异常。一个异常类似于一个错误,然而却更具有一般性。描述一个异常的最好的方法是使用emergency。尽管一个emergency可以不会是“致命的”,但是还是必须处理它。当在PHP中抛出一个异常时,执行的当前范围很快地被终止,不管它是一个函数,try..catch块还是脚本本身。然后,该异常遍历调用栈—终止每个执行范围,直到或者在一个try..catch块中捕获它或者它到达调用栈的顶部—此时它将生成一个致命错误。

  异常处理是PHP 5中的另外一个新特征,当与OOP联用时,它能够实现良好地控制错误处理和报告。一个try..catch块是一种处理异常的重要机制。一旦被捕获,脚本将会从异常被捕获和被处理的代码的下一行继续执行。

  如果查询失败,你需要改变你的execute函数以抛出一个异常。你将抛出一个称为QueryException的定制异常对象—导致错误的DBQuery对象被传递给它。

  列表3.抛出一个异常。

/**
*执行当前查询
*
* 执行当前查询—用提供的参数代替任何点位符
* .
*
* @参数: mixed $queryParams,... 查询参数
* @返回:资源A—参考描述执行查询的资源。
*/
public function execute($queryParams = )
{
 //例如: SELECT * FROM table WHERE name=:1S AND type=:2I AND level=:3N
 $args = func_get_args();
 if ($this->stored_procedure) {
  /*调用compile函数以得到查询*/
  $query = call_user_func_array(array($this, compile), $args);
 } else {
  /*一个存储过程没被初始化,因此,作为一种标准查询来执行之*/
  $query = $queryParams;
 }
 $result = $this->db->query($query);
 if (! $result) {
  throw new QueryException($this);
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage