in PHP

從 Curl 到 Guzzle, PHP HTTP client

[前言]

當我們使用 PHP 要爬網頁或做網路機器人的時候,第一個會想到的是:使用 CURL ,他是一個在 Linux 的套件,安裝之後可以使用的指令,因為有繼續發展函式庫的關係,所以陸續針對不同的程式語言開發了 LibCurl,不過 curl 其實在 PHP 不好用,其原因不外乎是使用 curl_init….. 等程序式函式庫而成的。對於一些寫習慣了 OOP 物件導向程式的人來說不習慣。因此在某些原因下,Guzzle, 這個 PHP HTTP client 就產生了。

[安裝]

PHP 最主要的 dependencies package manager 是 Composer 是一個套件管理器,能夠安裝各式套件且不需要匯入。

首先要先安裝好這個。

Guzzle 5.3.0 前置條件:

Requirements
需要 PHP 5.4.0
To use the PHP stream handler, allow_url_fopen must be enabled in your system’s php.ini. allow_url_fopen 設定需要被打開(設定:On)
To use the cURL handler, you must have a recent version of cURL >= 7.16.2 compiled with OpenSSL and zlib. cURL 版本需要 7.16.2 以上且 有把 OpenSSL and zlib 編譯進去

Step1:

下載 composer.phar,利用下面指令就會自動安裝最新版的 composer.phar

curl -sS https://getcomposer.org/installer | php

Step2:

當然也可以選擇手動安裝,進入下載頁面,拉到最下面有 Manual Download 字眼,為手動安裝。

Step3:編寫 composer.json 並執行:php composer.phar install 如果之前已經有使用 composer.json 則輸入:php composer.phar update

或直接在專案目錄下值接輸入:php composer.phar require guzzlehttp/guzzle

{
    "require": {
       "guzzlehttp/guzzle":"5.*.*"
    }
} 

我們安裝第五版,第五版與第六版是目前官方所支援的,寫法有異,這篇先以第五版做為範例。

Step3:接下來的範例,我用幾個常用的服務做為範例,分別是下再一個網頁, Google reCaptcha API驗證,和寄信服務MailGun (cURL),以及上傳圖床服務 imgur (用 cURL)等這四個範例。

[範例 1:Mailgun]

Mailgun 是一個發送信件的服務,相較自己架的Mail server 發信,信件不會被丟到垃圾信件中。也省去一些繁複的設定。

下面是一個使用 libcURL 的 PHP 程式碼:


function send_simple_message() {
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
     curl_setopt($ch, CURLOPT_USERPWD, 'api:key-your-key');
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
     curl_setopt($ch, CURLOPT_URL,
              'https://api.mailgun.net/v3/your-domain.mailgun.org/messages');
     curl_setopt($ch, CURLOPT_POSTFIELDS,
            array('from' => 'peter <peter279k@gmail.com>',
                  'to' => 'peter <peter279k@gmail.com>',
                  'subject' => 'Hello',
                  'text' => 'Hello World'));
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

如果用 Guzzle 寫的:其實不會差很多,主要是 Guzzle 是以 libcURL 為基礎的,用 OOP 物件導向的程設重新設計過,所以使用起來會比較直覺。

需注意的是,HTTP-BASIC 用法不太一樣,冒號隔開分別是,使用者名稱與密碼。


require "vendor/autoload.php";

$client = new GuzzleHttp\Client([
'defaults' => [
      'auth' => ['api', 'key-your-api-key'],
    ]
]);

$client -> setDefaultOption('verify', false);
$res = $client->post('https://api.mailgun.net/v3/your-domain.mailgun.org/messages', [
'body'=>[
    'from' => 'peter <peter279k@gmail.com>',
    'to' => 'peter <peter279k@gmail.com>',
    'subject' => 'Hello',
    'text' => 'Hello World'
  ]
]);
var_dump($res->json());

[範例 2:Imgur]

Imgur 是一個好用的圖床服務,通常會拿來上傳圖片,當然也有提供各式的 API 可供授權 authLoginURL 與上傳圖片。

下面是一個使用 libcURL 的 PHP 程式碼:


$client_id = "your-imgur-client-id";
$image = file_get_contents("/path/to/image.png");

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($image)));

$reply = curl_exec($ch);
curl_close($ch);

$reply = json_decode($reply, true);

var_dump($reply);

用 Guzzle HTTP Client 寫的:


$imageFile = file_get_contents("../imgur_result.png");

$client = new GuzzleHttp\Client([
     'defaults' => [
         'headers' => ['Authorization' => 'Client-ID 3aa5c24753e1656'],
     ]
]);

$res = $client->post('https://api.imgur.com/3/image.json', [
      'body'=>[
         'image' => base64_encode($imageFile)
      ]
]);

var_dump($res->json());

[範例 3: Google reCaptcha API]

[未完,待續……]

[Ref. 參考資料]

Mailgun心得筆記

Guzzle 5.3 docs

Mailgun 介紹

[後記]

下兩篇將會單獨介紹寄信服務與 Imgur 的圖床服務