WordPress中文开发手册

WordPress插件开发 — HTTP API

##介绍

HTTP代表超文本传输协议,是整个互联网的基础通信协议。 即使这是您第一次使用HTTP的经历,也许您可能比了解更多。 在最基本的层面上,HTTP的工作原理如下:

  • “你好,服务器XYZ,请问我有文件abc.html”
  • “好,你好,有一点客户,是的,你可能,这里是”

在PHP中发送HTTP请求有许多不同的方法。 WordPress HTTP API的目的是支持尽可能多的这些方法,并使用最适合特定请求的方法。

WordPress HTTP API也可用于与Twitter API或Google Maps API等其他API进行通信和交互。

HTTP方法

HTTP有几种描述特定类型操作的方法或动词。 虽然还有几个存在,WordPress已经预先建立了三个最常见的功能。 每当HTTP请求被发送时,也会传递一个方法来帮助服务器确定客户端请求哪种动作。

GET

GET用于检索数据。 这是迄今为止最常用的动词。 每次您查看网站或从API中提取数据时,都会看到GET请求的结果。 实际上,您的浏览器向您正在阅读的服务器发送GET请求,并请求用于构建此文章的数据。

POST

POST用于向服务器发送数据,以使服务器以某种方式进行操作。 例如,联系表。 当您在表单域中输入数据并单击提交按钮时,浏览器将收集数据,并将POST请求发送到服务器,并将其输入到表单中。 从那里,服务器将处理联系请求。

HEAD

HEAD不如其他两个人所熟知。 HEAD与GET请求基本相同,除了它不检索数据,只有关于数据的信息。 此数据描述了上次更新数据时,客户端是否应缓存数据,数据类型等。现代浏览器通常会将HEAD请求发送到先前访问过的页面,以确定是否有更新。 如果没有,您实际上可能会看到以前下载的页面副本,而不是使用带宽不必要地拉入同一个副本。

所有良好的API客户端在执行GET请求之前可以利用HEAD来潜在地节省带宽。 尽管如果HEAD表示有新数据,则需要两个单独的HTTP请求,具有GET请求的数据大小可能非常大。 当HEAD表示数据是新的或不应该被缓存时,只使用GET将有助于节省昂贵的带宽和加载时间。

自定义方法

还有其他HTTP方法,如PUT,DELETE,TRACE和CONNECT。 这些方法将不在本文中,因为没有预先构建的方法来在WordPress中使用它们,也不是API实现它们的常见方法。

根据您的服务器配置方式,您还可以实现您自己的其他HTTP方法。 总是冒险超越标准的方法,并为其他开发者创造客户端以消耗您的网站或API的巨大潜在限制,但是可以利用WordPress中的任何方法。 我们将在本文中简要介绍一下如何做到这一点。

响应码

HTTP使用数字和字符串响应代码。 而不是对每个的冗长解释,这里是标准响应代码。 您可以在创建API时定义自己的响应代码,但是除非您需要支持特定类型的响应,否则最好遵守标准代码。 自定义代码通常在1xx范围内。

代码类

三位数代码的最左边的数字可以快速看到响应类型。

状态码说明
2xx请求成功
3xx请求被重定向到另一个URL
4xx由于客户端错误请求失败。 通常无效的认证或丢失的数据
5xx由于服务器错误而请求失败。 常常丢失或配置错误的配置文件

通用代码

这些是您将遇到的最常见的代码。

状态码说明
200OK - 请求成功
301资源永久移动
302资源暂时移动
403禁止 - 通常是由于认证无效
404资源未找到
500内部服务器错误
503服务不可用

从API获取数据

GitHub提供了一个优秀的API,它不需要许多公共方面的应用程序注册,因此要演示其中的一些方法,示例将针对GitHub API。

通过wp_remote_get()函数在WordPress中获取数据非常简单。此函数具有以下两个参数:

  • $url – 从中检索数据的资源。 这必须是标准的HTTP格式
  • $args – 可选 - 您可以在此处传递一组参数来更改行为和标题,例如Cookie,跟随重定向等。

假定以下默认值,尽管可以通过$args参数更改它们:

  • method – GET
  • timeout – 5 – 放弃之前等待多久
  • redirection – 5 – 多少次遵循重定向。
  • httpversion – 1.0
  • blocking – true – 页面的其余部分是否等待完成加载,直到此操作完成?
  • headers – array()
  • body – null
  • cookies – array()

让我们使用一个GitHub用户帐户的URL,看看我们可以得到什么样的信息

$response = wp_remote_get( 'https://api.github.com/users/blobaugh' );

$response将包含有关我们的请求的所有标题,内容和其他元数据

Array
(
    [headers] => Array
        (
            [server] => nginx
            [date] => Fri, 05 Oct 2012 04:43:50 GMT
            [content-type] => application/json; charset=utf-8
            [connection] => close
            [status] => 200 OK
            [vary] => Accept
            [x-ratelimit-remaining] => 4988
            [content-length] => 594
            [last-modified] => Fri, 05 Oct 2012 04:39:58 GMT
            [etag] => "5d5e6f7a09462d6a2b473fb616a26d2a"
            [x-github-media-type] => github.beta
            [cache-control] => public, s-maxage=60, max-age=60
            [x-content-type-options] => nosniff
            [x-ratelimit-limit] => 5000
        )
 
    [body] => {"type":"User","login":"blobaugh","gravatar_id":"f25f324a47a1efdf7a745e0b2e3c878f","public_gists":1,"followers":22,"created_at":"2011-05-23T21:38:50Z","public_repos":31,"email":"ben@lobaugh.net","hireable":true,"blog":"http://ben.lobaugh.net","bio":null,"following":30,"name":"Ben Lobaugh","company":null,"avatar_url":"https://secure.gravatar.com/avatar/f25f324a47a1efdf7a745e0b2e3c878f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","id":806179,"html_url":"https://github.com/blobaugh","location":null,"url":"https://api.github.com/users/blobaugh"}
    [response] => Array
        (
            [preserved_text 5237511b45884ac6db1ff9d7e407f225 /] => 200
            [message] => OK
        )
 
    [cookies] => Array
        (
        )
 
    [filename] => 
)

所有相同的助手功能都可以与前两个功能一样使用。 这里的例外是HEAD永远不会返回一个body,因此元素将始终为空。

获得你一直想要的身体

只要身体可以使用wp_remote_retrieve_body()检索。 此函数只需要一个参数,来自其他检索的其他wp_remote_X函数的响应不是下一个值。

$response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
$body = wp_remote_retrieve_body( $response );

仍然使用前面的例子中的GitHub资源,$body将会

{"type":"User","login":"blobaugh","public_repos":31,"gravatar_id":"f25f324a47a1efdf7a745e0b2e3c878f","followers":22,"avatar_url":"https://secure.gravatar.com/avatar/f25f324a47a1efdf7a745e0b2e3c878f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","public_gists":1,"created_at":"2011-05-23T21:38:50Z","email":"ben@lobaugh.net","following":30,"name":"Ben Lobaugh","company":null,"hireable":true,"id":806179,"html_url":"https://github.com/blobaugh","blog":"http://ben.lobaugh.net","location":null,"bio":null,"url":"https://api.github.com/users/blobaugh"}

如果您没有任何其他操作来执行响应,除了获得身体,您可以将代码减少到一行

$body = wp_remote_retrieve_body( wp_remote_get( 'https://api.github.com/users/blobaugh' ) );

这些帮助函数中的许多功能也可以在一行上同样使用。

获取响应代码

您可能需要检查响应代码,以确保检索成功。 这可以通过wp_remote_retrieve_response_code()函数完成:

$response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
$http_code = wp_remote_retrieve_response_code( $response );

如果成功$http_code将包含200。

获取一个特定的头文件

如果你想要检索一个特定的标题,比如说最后一次修改,你可以用wp_remote_retrieve_header()这样做。 此功能需要两个参数

  • $response - 获取调用的响应
  • $header - 要检索的头的名称

检索最后修改的标题

$response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
$last_modified = wp_remote_retrieve_header( $response, 'last-modified' );

$ last_modified 将包含[last-modified] => Fri,05 Oct 2012 04:39:58 GMT
您还可以使用wp_remote_retrieve_headers($ response)检索数组中的所有头。

GET使用基本认证

受保护的API提供了许多不同类型的身份验证中的一种或多种。 HTTP基本身份验证是一种常见的,但不是非常安全的身份验证方法。 通过将“授权”传递给wp_remote_get()函数的第二个参数以及其他HTTP方法函数,可以在WordPress中使用。

$args = array(
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
    )
);
wp_remote_get( $url, $args );

将数据发布到API

相同的帮助方法(wp_remote_retrieve_body()等)可用于所有HTTP方法调用,并以相同的方式使用。

POST数据使用wp_remote_post()函数完成,并且与wp_remote_get()完全相同的参数。这里应该注意的是,您需要传递第二个参数的数组中的所有元素。食典提供默认的可接受值。您只需要关心发送的数据,所以其他值将被默认。

要将数据发送到服务器,您将需要构建一个关联的数据数组。该数据将被分配给“body”值。从服务器端的值将会出现在$ _POST变量中。即如果在服务器$ _POST ['myvar'] = 5上的body => array('myvar'=> 5)。

因为GitHub不允许POST到上一个例子中使用的API,这个例子将假装它是这样的。通常,如果要将数据POST到API,您需要联系API的维护者并获取API密钥或某种其他形式的身份验证令牌。这只是证明您的应用程序被允许以与用户对网站登录网站相同的方式操纵API上的数据。

假设我们提交的联系表单包含以下字段:姓名,电子邮件,主题,评论。要设置身体,我们执行以下操作:

$body = array(
    'name' => 'Jane Smith',
    'email' => 'some@email.com',
    'subject' => 'Checkout this API stuff',
    'comment' => 'I just read a great tutorial by this Ben Lobaugh. It taught me amazing things about interacting with APIs in WordPress! You gotta check it out!'
);

现在我们需要设置将被传递给wp_remote_post()的第二个参数的其余值,

$args = array(
    'body' => $body,
    'timeout' => '5',
    'redirection' => '5',
    'httpversion' => '1.0',
    'blocking' => true,
    'headers' => array(),
    'cookies' => array()
);

那么当然要打电话

$response = wp_remote_post( 'http://your-contact-form.com', $args );

对于那些不喜欢拼接在一起这里代码的人,整个片段

$body = array(
    'name' => 'Jane Smith',
    'email' => 'some@email.com',
    'subject' => 'Checkout this API stuff',
    'comment' => 'I just read a great tutorial by this Ben Lobaugh. It taught me amazing things about interacting with APIs in WordPress! You gotta check it out!'
);
 
$args = array(
    'body' => $body,
    'timeout' => '5',
    'redirection' => '5',
    'httpversion' => '1.0',
    'blocking' => true,
    'headers' => array(),
    'cookies' => array()
);
 
$response = wp_remote_post( 'http://your-contact-form.com', $args );

HEADING关闭带宽使用

API可能非常重要,有时候需要使用HEAD检查资源状态。在高流量API上,GET通常限于每分钟或小时的请求数。除非HEAD请求显示API上的数据已更新,否则不需要尝试GET请求。

如前所述,HEAD包含有关数据是否已被更新的数据,如果数据应该被缓存,何时到期缓存的副本,以及有时对API的请求的速率限制。

回到GitHub示例,这里有几个标题要注意。大多数这些标头是标准的,但是您应该始终检查API文档,以确保您了解哪些头命名为什么以及其目的。

  • x-ratelimit-limit - 一段时间内允许的请求数
  • x-ratelimit-remaining - 在时间段内剩余的可用请求数
  • content-length - 内容以字节为单位。如果内容相当大,警告用户可能很有用
  • last-modified - 资源上次修改时。对缓存工具非常有用
  • cache-control - 客户端应如何处理缓存

以下将检查我的GitHub用户帐户的HEAD值:

$response = wp_remote_head( 'https://api.github.com/users/blobaugh' );

$response应该看起来类似

Array
(
    [headers] => Array
        (
            [server] => nginx
            [date] => Fri, 05 Oct 2012 05:21:26 GMT
            [content-type] => application/json; charset=utf-8
            [connection] => close
            [status] => 200 OK
            [vary] => Accept
            [x-ratelimit-remaining] => 4982
            [content-length] => 594
            [last-modified] => Fri, 05 Oct 2012 04:39:58 GMT
            [etag] => "5d5e6f7a09462d6a2b473fb616a26d2a"
            [x-github-media-type] => github.beta
            [cache-control] => public, s-maxage=60, max-age=60
            [x-content-type-options] => nosniff
            [x-ratelimit-limit] => 5000
        )
 
    [body] => 
    [response] => Array
        (
            [preserved_text 39a8515bd2dce2aa06ee8a2a6656b1de /] => 200
            [message] => OK
        )
 
    [cookies] => Array
        (
        )
 
    [filename] => 
)

所有相同的助手功能都可以与前两个功能一样使用。 这里的例外是HEAD永远不会返回一个body,因此元素将始终为空。

做任何形式的请求

如果您需要使用上述功能不支持的HTTP方法发出请求,请不要惊慌。 发展WordPress的伟大人物已经想到了,并且亲切地提供了wp_remote_request()。 此函数使用与wp_remote_get()相同的两个参数,并允许您同时指定HTTP方法。 您需要传递哪些数据取决于您的方法。

要发送DELETE方法示例,您可能有以下类似的内容:

$args = array(
    'method' => 'DELETE'
);
$response = wp_remote_request( 'http://some-api.com/object/to/delete', $args );

缓存介绍

缓存是一种习惯,通常需要大量时间构建的对象或对象被保存到快速对象存储中,以便稍后的请求快速检索。这样就可以避免花费时间取回并再次构建对象。缓存是一个广泛的主题,是网站优化的一部分,可以自己完成一系列的文章。以下只是缓存的介绍和一个简单而有效的方法来快速设置缓存的API响应。

为什么要缓存API响应?那么,房间里的大象是因为外部API会减慢你的网站。许多顾问会告诉您,利用外部API将通过减少连接数量和处理性能以及成本高的带宽来提高网站的性能,但有时这根本不是真的。

您的服务器可以发送数据的速度与远程服务器处理请求所需的时间,构建数据并将其发送回来,这是一个很好的平衡。第二个显着的方面是,许多API在一段时间内具有有限数量的请求,并且可能一次应用程序对连接数量的限制。缓存有助于通过在服务器上放置数据副本来解决这些难题,直到需要刷新。

什么时候应该缓存?

这个简单的答案是总是,但再次有时你不应该。 如果您正在处理实时数据或API专门指出不缓存在标题中,您可能不想缓存,但对于所有其他情况,通常最好缓存从API检索的任何资源。

WordPress瞬变

WordPress瞬态提供了一种方便的方法来存储和使用缓存的对象。 瞬态生存指定的时间,或者直到您需要它们在API更新资源时过期。 在WordPress中使用瞬态功能可能是您遇到的最简单的缓存系统。 只有三个功能 to do all the heavy lifting for you.

缓存一个对象(设置一个瞬态)

使用set_transient()函数来缓存对象。 此功能需要以下三个参数:

  • $transient - 短暂的名称供将来参考
  • $value - 瞬态值
  • $expiration - 从暂时保存到到期之前有多少秒钟

从上面缓存GitHub用户信息响应一个小时的例子是

$response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
 
set_transient( 'blobaugh_github_userinfo', $response, 60*60 );

获取一个缓存的对象(获取一个暂时的)

获取缓存的对象比设置一个临时对象要复杂得多。 您需要请求瞬态,但是您还需要检查以确定瞬态是否已过期,如果是这样,获取更新的数据。 通常,set_transient()调用是在get_transient()调用之内进行的。 以下是获取GitHub用户配置文件的临时数据的示例:

$github_userinfo = get_transient( 'blobaugh_github_userinfo' );
 
if( false === $github_userinfo ) {
    // Transient expired, refresh the data
    $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
    set_transient( 'blobaugh_github_userinfo', $response, 60*60 );
}
// Use $github_userinfo as you will

删除缓存的对象(删除一个瞬态)

删除缓存的对象是所有瞬态函数中最简单的,只需传递一个瞬态名称的参数即可完成。

要删除Github用户信息:

delete_transient( 'blobaugh_github_userinfo' );
Tags ,