關於WordPress HTTP API的一些知識點

wordpress-http-api

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標頭示例

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請求

讓我們通過從閃電博網站部落格中獲取標頭資訊來進行快速測試。您可以在外掛或主題中的任何位置執行此操作,但是顯然應該在測試環境中進行操作,以確保不會在實時站點上輸出不需要的文字。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$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 )
$response = wp_remote_head( 'https://www.wbolt.com/tw/blog' ); 
var_dump( $response )

從響應中可以看到,body部分為空(因為我們使用的是HEAD方法),並且顯示了所有標題。要僅獲取標頭而不包含所有其他陣列成員,我們可以使用wp_remote_retrieve_headers()函式。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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介面

Twitter API介面

對於開發人員而言,最大障礙是,使API呼叫正常工作所需的大量新內容。您需要了解HTTP,如何發出請求以及如何正確進行身份驗證,否則,每個呼叫都會失敗。讓我們看一下Twitter API的示例,因為它們提供了非常詳細的文件。

我們將研究僅應用程式身份驗證(這是一個更簡單的流程),按照Twitter建議的相同步驟進行操作。在開始之前,請確保建立一個Twitter應用程式

您應該可以將下面的程式碼新增到主題或外掛中的任何位置,並請確保使用測試站點!

第1步:編碼CONSUMER KEY和SECRET

建立應用程式後,你應該會獲取到一個CONSUMER KEY和CONSUMER SECRET。為了使事情變得容易,讓我們建立一個常量,為我們儲存這些資訊。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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中,這很容易做到!

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$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,我們將使用第二個引數來處理所有其他要求。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$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 );
$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 );

標頭需要作為陣列新增,標頭型別是鍵,值是陣列成員的值;主體應該是一個字串。如果成功,您應該會看到與以下類似的響應。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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函式來檢索它。參照前面的示例,我們可以使用以下程式碼來獲取訪問令牌:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$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陣列。您可以使用此陣列的各種屬性來顯示推文或處理資料。

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$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 )
$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的技巧和竅門,請在評論中告訴我們!

評論留言