_goodreads_fetch_bookshelf() 函数的工作是使用与 Goodreads 站点之间的HTTP 连接取回XML内容。一旦完成,它将把格式化的工作交给另一个函数完成。
我们先完整地看一遍这个函数:
/** * Retrieve information from the Goodreads bookshelp XML API. * * This makes an HTTP connection to the given URL, and * retrieves XML data, which it then attempts to format * for display. * * @param $url * URL to the goodreads bookshelf. * @param $num_items * Number of items to include in results. * @return * String containing the bookshelf. */ function _goodreads_fetch_bookshelf($url, $num_items=3) { $http_result = drupal_http_request($url); if ($http_result->code == 200) { $doc = simplexml_load_string($http_result->data); if ($doc === false) { $msg = "Error parsing bookshelf XML for %url: %msg."; $vars = array('%url'=>$url, '%msg'=>$e->getMessage()); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("Getting the bookshelf resulted in an error."); } return _goodreads_block_content($doc, $num_items); // Otherwise we don't have any data } else { $msg = 'No content from %url.'; $vars = array('%url' => $url); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible."); } }
遵循 Drupal 的编码惯例,上述代码中的第一块儿是 API 描述:
/**
* Retrieve information from the Goodreads bookshelp XML API.
*
* This makes an HTTP connection to the given URL, and retrieves
* XML data, which it then attempts to format for display.
*
* @param $url
* URL to the goodreads bookshelf.
* @param $num_items
* Number of items to include in results.
* @return
* String containing the bookshelf.
*/
这是个典型的函数文档块。开头第一句是函数概述。第一句话后面通常跟着几个句子进一步说明函数是做什么的。
在靠近文档块结尾的部分,有两个特殊的关键字(以 @ 符号开头)用来说明此函数的参数和可能的返回值。
如果函数不是钩子实现函数,任何其它模块函数都应该使用这种类型的文档。
现在我们看看函数方法本身,先看头几行:
function _goodreads_fetch_bookshelf($url, $num_items=3) {
$http_result = drupal_http_request($url);
这个函数需要两个参数。$url 参数是必备的,它应该包含远程站点的 URL,$num_items 是可选参数,它应该指明来自 feed 的返回值的最多有几项。
尽管我们调用 _goodreads_fetch_bookshelf() 函数时没有使用 $num_items 参数,不过把它加入模块的配置参数应该是个好的做法。
注意:这个函数做的第一件事是使用 Drupal 的内建函数drupal_http_request(),这个函数位于 includes/common.php 库中。这个函数使用提供的 URL 建立与远程站点的 HTTP 连接,然后执行一个 HTTP GET 请求。
函数 drupal_http_request() 返回一个包含响应代码(来自服务器或 socket 库)的对象,HTTP 头部,以及从远程服务器上返回的数据。
提示:偶尔有人批评 Drupal 没有使用 PHP 的面向对象特性。实际上,它使用了——但不像其它项目那么明显。极少使用构造函数,但在整个框架内都在使用对象。例如,此处 Drupal 核心函数返回了一个对象。
当 drupal_http_request() 函数执行完后,$http_result 对象中包含返回的信息。我们应该查明的第一件事是 HTTP 请求是否成功了——它是否已经连接上并取回了我们让它获取的数据。
我们可以从响应代码中获得此信息,如果存在网络错误,响应代码将被设为负数,如果连接成功,将被设为 HTTP 响应代码之一。
我们知道,如果服务器的响应代码是 200(OK),意味着我们已经取回了一些数据。
提示:在更健壮的应用程序中,我们应该同时检查重定向消息(301, 302, 303, 和 307)以及其它类似情况。只要再增加一点代码,我们就可以把模块配置为能够跟踪重定向。
我们的简单模块将只是把任何其它响应都视为出错:
if ($http_result->code == 200) { // ...Process response code goes here... // Otherwise we don't have any data } else { $msg = 'No content from %url.'; $vars = array( '%url' => $url ); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible."); }
首先,我们看看如果响应代码不是 200 会怎么样:
} else { $msg = 'No content from %url.'; $vars = array( '%url' => $url ); watchdog('goodreads', $msg, $vars, WATCHDOG_WARNING); return t("The bookshelf is not accessible."); }
如果请求失败,我们想要做两件事:我们想把错误记入日志,然后通知用户(用友好的方式)我们无法获得内容。现在让我们略微了解一下 Drupal 的日志机制。
评论
发表新评论