
WordPress HTTP API由許多功能組成,可以幫助開發人員更輕鬆地進行HTTP呼叫。不再需要擺弄file_get_contents或cURL,只需一個統一的介面即可。與第三方API進行互動非常好,尤其是與Twitter,Facebook,MailChimp等其他具有REST功能的API互動時。
HTTP基礎
我們都已經知道HTTP的實際應用。實際上,如果這是您第一次訪問Web,那麼您已經看到HTTP發揮了神奇的作用。HTTP是一種網路協議,用於跨Interweb傳遞所有檔案和資料(資源)。
基本上有兩個部分:HTTP請求和HTTP響應(即事務)。請求和響應在結構上都非常相似,它們都有四個部分:
- 起始行(請求行)
- 零個或多個標題行
- 空行
- 可選的body內容
The Initial Line起始行
請求使用起始行傳送三個資訊:方法名稱,路徑和HTTP版本。例如,在檢視閃電博部落格頁面時,您會在請求的第一行看到它。
GET /blog HTTP/1.1
響應還提供了三部分資訊,儘管有些不同:HTTP版本,響應程式碼和響應描述。向閃電博網站部落格發出請求時,它將傳送帶有以下起始行行的HTTP響應:
HTTP/1.0 200 OK
Headers標頭
標頭包含有關請求或響應的各種資訊。HTTP 1.1定義了46種報頭型別,但僅一種(僅用於請求)是必需的“主機”報頭。如開啟閃電博網站的部落格頁面,Chrome開發人員工具中的螢幕截圖,其中顯示了一些標頭以及傳送給閃電博網站的請求:

Header標頭示例
Body
Body通常包含有關所請求資源的資料。如果您向閃電博網站部落格傳送GET請求,則應該收到在主體內容中呈現頁面(資源)所需的HTML。
更多資訊
這就是您現在需要了解的所有關於HTTP的資訊。我們將主要集中在方法名稱(GET,POST等),標頭和主體上。如果您想了解更多資訊,推薦閱讀James Marshall對HTTP的解釋,這是一篇非常不錯的關於HTTP入門的文章。
關於Restful APIs
Restful API或REST方法旨在提供一種與應用程式進行互動的簡單且標準的方式。它通常與HTTP結合使用,以建立一個非常易於理解的互動系統。它基於路徑和HTTP verbs。
HTTP verbs與我們之前看到的方法名稱相同,最常見的是:GET,POST,PUT,DELETE。我認為PUT是唯一的模稜兩可的工具,可以將其視為更新命令。將這些verbs與路徑一起使用時,我們可以構建一個有意義的系統:
GET /post/1/
將用於檢索ID為1的文章。DELETE /post/1/
將用於刪除同一文章。我們還可以使用PUT /post/1/
來更新它,在請求正文和標頭中提供相關資訊。
您可以看到,僅通過將HTTP版本附加到上面的程式碼中,我們實際上就有了HTTP事務的起始行,這是該系統如此強大的原因之一。
使用WordPress HTTP API
擁有所有這些知識,我們可以輕鬆掌握WordPress HTTP API的工作方式。發出請求和攔截響應的四種方法是:
wp_remote_get()
wp_remote_post()
wp_remote_head()
wp_remote_request()
前兩個函式是不言自明的,它們在請求中分別使用GET和POST方法。第三個函式使用HEAD方法,我們還沒有討論過。此方法僅用於檢索響應的標頭。如果我們只需要一些關於資源的後設資料,則可以節省很多開銷。最後一個函式是通用函式,您可以在函式的引數中指定要使用的方法。
我們可以使用五個附加函式來檢索響應的特定部分。這些基本上是引導我們接收到的大量資料的捷徑:
wp_remote_retrieve_body()
wp_remote_retrieve_header()
wp_remote_retrieve_headers()
wp_remote_retrieve_response_code()
wp_remote_retrieve_response_message()
第一個HTTP請求
讓我們通過從閃電博網站部落格中獲取標頭資訊來進行快速測試。您可以在外掛或主題中的任何位置執行此操作,但是顯然應該在測試環境中進行操作,以確保不會在實時站點上輸出不需要的文字。
$response = wp_remote_head( 'https://www.wbolt.com/tw/blog' );
$response = wp_remote_head( 'https://www.wbolt.com/tw/blog' );
var_dump( $response )
$response = wp_remote_head( 'https://www.wbolt.com/tw/blog' );
var_dump( $response )
從響應中可以看到,body部分為空(因為我們使用的是HEAD方法),並且顯示了所有標題。要僅獲取標頭而不包含所有其他陣列成員,我們可以使用wp_remote_retrieve_headers()
函式。
'server' => string 'nginx' (length=5)
'date' => string 'Wed, 22 Jul 2015 14:22:07 GMT' (length=29)
'content-type' => string 'text/html; charset=UTF-8' (length=24)
'connection' => string 'close' (length=5)
'vary' => string 'Accept-Encoding' (length=15)
'x-pingback' => string 'https://www.wbolt.com/tw/xmlrpc.php' (length=29)
'x-powered-by' => string 'HHVM/3.8.0' (length=10)
'link' => string '; rel="https://github.com/WP-API/WP-API"' (length=68)
'x-frame-options' => string 'DENY' (length=4)
'x-content-type-options' => string 'nosniff' (length=7)
'strict-transport-security' => string 'max-age=31536000' (length=16)
'x-wbolt-cache' => string 'HIT' (length=3)
'content-encoding' => string 'gzip' (length=4)
'body' => string '' (length=0)
'message' => string 'OK' (length=2)
array (size=5)
'headers' =>
array (size=13)
'server' => string 'nginx' (length=5)
'date' => string 'Wed, 22 Jul 2015 14:22:07 GMT' (length=29)
'content-type' => string 'text/html; charset=UTF-8' (length=24)
'connection' => string 'close' (length=5)
'vary' => string 'Accept-Encoding' (length=15)
'x-pingback' => string 'https://www.wbolt.com/tw/xmlrpc.php' (length=29)
'x-powered-by' => string 'HHVM/3.8.0' (length=10)
'link' => string '; rel="https://github.com/WP-API/WP-API"' (length=68)
'x-frame-options' => string 'DENY' (length=4)
'x-content-type-options' => string 'nosniff' (length=7)
'strict-transport-security' => string 'max-age=31536000' (length=16)
'x-wbolt-cache' => string 'HIT' (length=3)
'content-encoding' => string 'gzip' (length=4)
'body' => string '' (length=0)
'response' =>
array (size=2)
'code' => int 200
'message' => string 'OK' (length=2)
'cookies' =>
array (size=0)
empty
'filename' => null
array (size=5)
'headers' =>
array (size=13)
'server' => string 'nginx' (length=5)
'date' => string 'Wed, 22 Jul 2015 14:22:07 GMT' (length=29)
'content-type' => string 'text/html; charset=UTF-8' (length=24)
'connection' => string 'close' (length=5)
'vary' => string 'Accept-Encoding' (length=15)
'x-pingback' => string 'https://www.wbolt.com/tw/xmlrpc.php' (length=29)
'x-powered-by' => string 'HHVM/3.8.0' (length=10)
'link' => string '; rel="https://github.com/WP-API/WP-API"' (length=68)
'x-frame-options' => string 'DENY' (length=4)
'x-content-type-options' => string 'nosniff' (length=7)
'strict-transport-security' => string 'max-age=31536000' (length=16)
'x-wbolt-cache' => string 'HIT' (length=3)
'content-encoding' => string 'gzip' (length=4)
'body' => string '' (length=0)
'response' =>
array (size=2)
'code' => int 200
'message' => string 'OK' (length=2)
'cookies' =>
array (size=0)
empty
'filename' => null
瞭解API

Twitter API介面
對於開發人員而言,最大障礙是,使API呼叫正常工作所需的大量新內容。您需要了解HTTP,如何發出請求以及如何正確進行身份驗證,否則,每個呼叫都會失敗。讓我們看一下Twitter API的示例,因為它們提供了非常詳細的文件。
我們將研究僅應用程式身份驗證(這是一個更簡單的流程),按照Twitter建議的相同步驟進行操作。在開始之前,請確保建立一個Twitter應用程式。
您應該可以將下面的程式碼新增到主題或外掛中的任何位置,並請確保使用測試站點!
第1步:編碼CONSUMER KEY和SECRET
建立應用程式後,你應該會獲取到一個CONSUMER KEY和CONSUMER SECRET。為了使事情變得容易,讓我們建立一個常量,為我們儲存這些資訊。
define( 'TWITTER_CONSUMER_KEY', '12disnir382jeqwdasd23wdasi' );
define( 'TWITTER_CONSUMER_SECRET', '23wdajskduhtrq2c32cuq9r8uhuf' )
define( 'TWITTER_CONSUMER_KEY', '12disnir382jeqwdasd23wdasi' );
define( 'TWITTER_CONSUMER_SECRET', '23wdajskduhtrq2c32cuq9r8uhuf' )
define( 'TWITTER_CONSUMER_KEY', '12disnir382jeqwdasd23wdasi' );
define( 'TWITTER_CONSUMER_SECRET', '23wdajskduhtrq2c32cuq9r8uhuf' )
在文件中列出了建立這些檔案的編碼版本的三個步驟:
- URL編碼KEY和SECRET
- 用冒號連線它們
- Base64編碼整個字串
在PHP中,這很容易做到!
$key = urlencode( TWITTER_CONSUMER_KEY );
$secret = urlencode( TWITTER_CONSUMER_SECRET );
$concatenated = $key . ':' . $secret;
$encoded = base64_encode( $concatenated );
$key = urlencode( TWITTER_CONSUMER_KEY );
$secret = urlencode( TWITTER_CONSUMER_SECRET );
$concatenated = $key . ':' . $secret;
$encoded = base64_encode( $concatenated );
$key = urlencode( TWITTER_CONSUMER_KEY );
$secret = urlencode( TWITTER_CONSUMER_SECRET );
$concatenated = $key . ':' . $secret;
$encoded = base64_encode( $concatenated );
第2步:獲取承載token
您無需使用實際密碼,而是向Twitter傳送您的編碼字串(使用您的API憑據),並且會收到一個臨時通行證,該通行證在一定時間內有效。為此,我們將發出一個HTTP請求,這是Twitter所說的:
- 該請求必須是HTTP POST請求。
- 該請求必須包含值為Basic的Authorization標頭。
- 該請求必須包含Content-Type標頭,其值是application/x-www-form-urlencoded;charset=UTF-8。
- 請求的正文必須為grant_type = client_credentials。
讓我們從基礎開始。需要POST請求,因此我們將使用wp_remote_post()
。該函式帶有引數;第一個是URL,第二個包含可選引數。該網址為https://api.twitter.com/oauth2/token
,我們將使用第二個引數來處理所有其他要求。
'Authorization' => 'Basic ' . $encoded,
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
'body' => 'grant_type=client_credentials'
$response = wp_remote_post( 'https://api.twitter.com/oauth2/token', $args );
$args = array(
'headers' => array(
'Authorization' => 'Basic ' . $encoded,
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
),
'body' => 'grant_type=client_credentials'
);
$response = wp_remote_post( 'https://api.twitter.com/oauth2/token', $args );
$args = array(
'headers' => array(
'Authorization' => 'Basic ' . $encoded,
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
),
'body' => 'grant_type=client_credentials'
);
$response = wp_remote_post( 'https://api.twitter.com/oauth2/token', $args );
標頭需要作為陣列新增,標頭型別是鍵,值是陣列成員的值;主體應該是一個字串。如果成功,您應該會看到與以下類似的響應。
'cache-control' => string 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0' (length=62)
'content-disposition' => string 'attachment; filename=json.json' (length=30)
'content-encoding' => string 'deflate' (length=7)
'content-length' => string '142' (length=3)
'content-type' => string 'application/json;charset=utf-8' (length=30)
'date' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'expires' => string 'Tue, 31 Mar 1981 05:00:00 GMT' (length=29)
'last-modified' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'ml' => string 'A' (length=1)
'pragma' => string 'no-cache' (length=8)
'server' => string 'tsa_b' (length=5)
'set-cookie' => string 'guest_id=v1%3A14375720938219946; Domain=.twitter.com; Path=/; Expires=Fri, 21-Jul-2017 14:47:37 UTC' (length=100)
'status' => string '200 OK' (length=6)
'strict-transport-security' => string 'max-age=631138519' (length=17)
'x-connection-hash' => string 'd8b10926f99dwef93rd7edbe5a71a97a' (length=32)
'x-content-type-options' => string 'nosniff' (length=7)
'x-frame-options' => string 'SAMEORIGIN' (length=10)
'x-response-time' => string '34' (length=2)
'x-transaction' => string 'ef0ebwefweece62ef' (length=16)
'x-tsa-request-body-time' => string '0' (length=1)
'x-twitter-response-tags' => string 'BouncerCompliant' (length=16)
'x-ua-compatible' => string 'IE=edge,chrome=1' (length=16)
'x-xss-protection' => string '1; mode=block' (length=13)
'body' => string '{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAFoafQAAAAAAqg%2BxmuH83hjsod6crH5bKTUX9Arc%3D5dWpp0XCTDjyiXxMC7LDLg8JbzPdGlCsJi2R1qjY1FMksTAFyG"}' (length=155)
'message' => string 'OK' (length=2)
object(WP_Http_Cookie)[303]
public 'name' => string 'guest_id' (length=8)
public 'value' => string 'v1:143757645770219946' (length=21)
public 'expires' => int 1500648457
public 'path' => string '/' (length=1)
public 'domain' => string '.twitter.com' (length=12)
array (size=5)
'headers' =>
array (size=23)
'cache-control' => string 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0' (length=62)
'content-disposition' => string 'attachment; filename=json.json' (length=30)
'content-encoding' => string 'deflate' (length=7)
'content-length' => string '142' (length=3)
'content-type' => string 'application/json;charset=utf-8' (length=30)
'date' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'expires' => string 'Tue, 31 Mar 1981 05:00:00 GMT' (length=29)
'last-modified' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'ml' => string 'A' (length=1)
'pragma' => string 'no-cache' (length=8)
'server' => string 'tsa_b' (length=5)
'set-cookie' => string 'guest_id=v1%3A14375720938219946; Domain=.twitter.com; Path=/; Expires=Fri, 21-Jul-2017 14:47:37 UTC' (length=100)
'status' => string '200 OK' (length=6)
'strict-transport-security' => string 'max-age=631138519' (length=17)
'x-connection-hash' => string 'd8b10926f99dwef93rd7edbe5a71a97a' (length=32)
'x-content-type-options' => string 'nosniff' (length=7)
'x-frame-options' => string 'SAMEORIGIN' (length=10)
'x-response-time' => string '34' (length=2)
'x-transaction' => string 'ef0ebwefweece62ef' (length=16)
'x-tsa-request-body-time' => string '0' (length=1)
'x-twitter-response-tags' => string 'BouncerCompliant' (length=16)
'x-ua-compatible' => string 'IE=edge,chrome=1' (length=16)
'x-xss-protection' => string '1; mode=block' (length=13)
'body' => string '{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAFoafQAAAAAAqg%2BxmuH83hjsod6crH5bKTUX9Arc%3D5dWpp0XCTDjyiXxMC7LDLg8JbzPdGlCsJi2R1qjY1FMksTAFyG"}' (length=155)
'response' =>
array (size=2)
'code' => int 200
'message' => string 'OK' (length=2)
'cookies' =>
array (size=1)
0 =>
object(WP_Http_Cookie)[303]
public 'name' => string 'guest_id' (length=8)
public 'value' => string 'v1:143757645770219946' (length=21)
public 'expires' => int 1500648457
public 'path' => string '/' (length=1)
public 'domain' => string '.twitter.com' (length=12)
'filename' => null
array (size=5)
'headers' =>
array (size=23)
'cache-control' => string 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0' (length=62)
'content-disposition' => string 'attachment; filename=json.json' (length=30)
'content-encoding' => string 'deflate' (length=7)
'content-length' => string '142' (length=3)
'content-type' => string 'application/json;charset=utf-8' (length=30)
'date' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'expires' => string 'Tue, 31 Mar 1981 05:00:00 GMT' (length=29)
'last-modified' => string 'Wed, 22 Jul 2015 14:47:37 GMT' (length=29)
'ml' => string 'A' (length=1)
'pragma' => string 'no-cache' (length=8)
'server' => string 'tsa_b' (length=5)
'set-cookie' => string 'guest_id=v1%3A14375720938219946; Domain=.twitter.com; Path=/; Expires=Fri, 21-Jul-2017 14:47:37 UTC' (length=100)
'status' => string '200 OK' (length=6)
'strict-transport-security' => string 'max-age=631138519' (length=17)
'x-connection-hash' => string 'd8b10926f99dwef93rd7edbe5a71a97a' (length=32)
'x-content-type-options' => string 'nosniff' (length=7)
'x-frame-options' => string 'SAMEORIGIN' (length=10)
'x-response-time' => string '34' (length=2)
'x-transaction' => string 'ef0ebwefweece62ef' (length=16)
'x-tsa-request-body-time' => string '0' (length=1)
'x-twitter-response-tags' => string 'BouncerCompliant' (length=16)
'x-ua-compatible' => string 'IE=edge,chrome=1' (length=16)
'x-xss-protection' => string '1; mode=block' (length=13)
'body' => string '{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAFoafQAAAAAAqg%2BxmuH83hjsod6crH5bKTUX9Arc%3D5dWpp0XCTDjyiXxMC7LDLg8JbzPdGlCsJi2R1qjY1FMksTAFyG"}' (length=155)
'response' =>
array (size=2)
'code' => int 200
'message' => string 'OK' (length=2)
'cookies' =>
array (size=1)
0 =>
object(WP_Http_Cookie)[303]
public 'name' => string 'guest_id' (length=8)
public 'value' => string 'v1:143757645770219946' (length=21)
public 'expires' => int 1500648457
public 'path' => string '/' (length=1)
public 'domain' => string '.twitter.com' (length=12)
'filename' => null
所有這些的主要highlight是可以在響應正文中找到的訪問令牌。現在讓我們使用WordPress函式來檢索它。參照前面的示例,我們可以使用以下程式碼來獲取訪問令牌:
$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body, true );
$access_token = $body['access_token'];
$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body, true );
$access_token = $body['access_token'];
$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body, true );
$access_token = $body['access_token'];
步驟3:使用不記名token
最後一步就是在所有其他API呼叫中使用此承載令牌。我們需要將其新增為“Authorization”標頭,其值是:Bearer [bearer_token]
。讓我們做一個簡單的API呼叫,它將使用user_timeline路徑檢索使用者的最新推文。
最後,該$tweets
變數將包含一個tweet陣列。您可以使用此陣列的各種屬性來顯示推文或處理資料。
$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=danielpataki&count=3';
'Authorization' => 'Bearer ' . $access_token,
$response = wp_remote_get( $url, $args );
$tweets = json_decode( wp_remote_retrieve_body($response), true )
$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=danielpataki&count=3';
$args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $access_token,
),
);
$response = wp_remote_get( $url, $args );
$tweets = json_decode( wp_remote_retrieve_body($response), true )
$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=danielpataki&count=3';
$args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $access_token,
),
);
$response = wp_remote_get( $url, $args );
$tweets = json_decode( wp_remote_retrieve_body($response), true )
小結
如您所見,使用WordPress HTTP API連線到外部服務並不難。當今的許多現代API都是基於相同的REST原理構建的-一旦您學習了一個REST原理,您就會很快地掌握其他REST原理。
請記住,每當文件要求您使用正文時,請使用正文,並且在需要標題時,只需新增所需的數量即可。然後,檢視響應,將其轉換為陣列,獲取所需的資料並使用它,就這麼簡單。
如果以前有人使用過特別好或不好的API,或者您有一些使用WordPress HTTP API的技巧和竅門,請在評論中告訴我們!
評論留言