それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

phpのcurl ライブラリの使い方のHTTP実例いっぱい-post や json でAPIリクエストとか

cURL ライブラリ

php には cURL ライブラリ があって、このCライブラリのラッパーを使うことでほとんどのネットワークリクエストを扱うことが出来る。

cURLの本家は http://curl.haxx.se/ で、ここでlibcurl を一式準備してC言語からネットワークリクエストが扱えるんだけど、良くわからないし、C言語自体の使い方にトラブルことも考えられる。

phpcURLを使うメリット

パッケージとして提供されていて、どこでも簡単にHTTPリクエストを扱うことが出来る。

php だけで書かれたHTTPリクエストライブラリは設計が古臭かったりしてちょっと・・・

file_get_contentsでも出来るんだけど、敢えてcURLで作るのもなれると便利だったりするよ。

curl の基本的な使い方

php の libcurl 関数はC言語のそれと同じような感じになっていて、初期化後にオプションを渡す。

  • curl を 初期化
  • オプション値を設定
  • オプション値を設定
  • オプション値を設定
  • オプション値を設定
  • オプション値を設定
  • リクエスト実行

このオプションがわかりにくい・・・⇛ オプション

オプションがいっぱいあって、面食らう人が多いんじゃないだろうか。

なので、よく使いそうなHTTPリクエストのcURLサンプル作成しておきました。

curl で HTTP GET

最初に、簡単な例です。HTTP GETで 初期化、オプション値設定、実行。このの流れを頭に入れまs。

<?php
$url = "http://www.yahoo.co.jp";

$curl = curl_init($url); // 初期化!

$options = array(           // オプション配列
  //HEADER
  CURLOPT_HTTPHEADER => array(
  ),
  //Method
  CURLOPT_HTTPGET => true,//GET
);

//set options
curl_setopt_array($curl, $options); /// オプション値を設定
// request
$result = curl_exec($curl); // リクエスト実行
//print
echo $result;
?>

これだけ。簡単ですね。file_get_contentsで1行で書けることをワザワザこんなことシないかもしれない。ポイントは、 $options変数に、HTTPのリクエストに関することやレスポンスの取得についてのあれこれがまとまるということ。$option変数さえ作ってしまえばあとは楽です。

覚えたことは初期化➝オプション値➝実行です。

オプション値は再利用しやすいよう、配列変数に入れておきます。

任意のHTTP ヘッダを付加することが出来る

オプション値を変えるとヘッダを追加できます。ヘッダのオプションで任意のヘッダを付けられます。

たとえば、Cookieや Authorization などもできます。

<?php
$options = array(
  //HEADER
  CURLOPT_HTTPHEADER => array(
      "Authorization: Bearer access_token",
  ),
  //Method
  CURLOPT_HTTPGET => true,//GET
);

$optionさえ保存しておけば抽象化が可能

ここが cURLのメリットだと思うんだ。cURLに渡すオプションを作るだけで、HTTPリクエストの使い回しが出来る。

<?php

$options = my_something( $options );
if( $my_args ){
  $options = next_must_fields( $options );
}
if( $my_args2 ){
  $options = some_fields( $options );
}
curl_setopt_array($curl, $options);
// request
$result = curl_exec($curl);

このように、option さえ使いまわしておけば、条件に応じて、HTTPリクエストを分岐させてコードの共通化が出来た。

cURLで HTTP POST

POSTするときは、 CURLOPT_POST のフラグをセットするだけ。

      CURLOPT_POST => true,//POST

以下がPOSTでデータを送信するサンプル。

$options変数の中身だけが変わっていて、コードの残り部分はGETと共通です。

<?php

$url = "http://www.yahoo.co.jp";

$curl = curl_init($url);

$options = array(
  //HEADER
  CURLOPT_HTTPHEADER => array(
      'Accept: application/json',
  ),
  //Method
  CURLOPT_POST => true,//POST
  //body
  CURLOPT_POSTFIELDS => http_build_query($post_args), 
);

//set options
curl_setopt_array($curl, $options);
// request
$result = curl_exec($curl);

echo $result;

?>

POSTの時は、 CURLOPT_POST をセットしてCURLOPT_POSTFIELDSにフィールをセットする。

注意点、空のボディを送信するとき(APIのPOSTだけをCall)のような場合でもフィールドは必須。空文字をセットしないとContent-Length: -1 を送信してしまう。

たとえば、JSONAPIをリクエストで投げつけるとき

<?php 
    $body = '{"sample":"Helloworld"}'
    $curl = curl_init($url);
    $options = [
      // オプション配列
      //HEADER
      CURLOPT_HTTPHEADER => [
        'Content-Type: application/json', // ←ここ文字列でHTTPヘッダ入れるので注意
      ],
      CURLOPT_POST=>true,
      CURLOPT_POSTFIELDS=>$body,
    ];
   //set options
   curl_setopt_array($curl, $options);
   // request
  $result = curl_exec($curl);

echo $result;

cURL で HTTP PUTリクエス

http の put リクエスを送るときもだいたい同じ。

次の例は、サーバにPUTリクエストでJSONを送信している。

<?php
$url = "http://www.yahoo.co.jp";

$curl = curl_init($url);

$options = array(
  //HEADER
  CURLOPT_HTTPHEADER => array(
      'Content-Type: application/json',
  ),
  //Method
  CURLOPT_CUSTOMREQUEST => "PUT",//PUT
  //body
  CURLOPT_POSTFIELDS => json_encode($data), // 本文
);

//set options
curl_setopt_array($curl, $options);
// request
$result = curl_exec($curl);

echo $result;

cURL で HTTP DELETE

HTTPのDELETEの場合は、ちょっとだけオプションが違う。

HTTPメソッド名を直接指定する。

<?php 
 CURLOPT_CUSTOMREQUEST => "DELETE",//DELETE

以下の例はサーバーにDELETEメソッドを送信している。

<?php
$url = "http://www.yahoo.co.jp";

$curl = curl_init($url);

///
$options = array(
  //HEADER
  CURLOPT_HTTPHEADER => array(
      'Content-Type: application/json',
  ),
  //Method
  CURLOPT_CUSTOMREQUEST => "DELETE",//DELETE
  //body
);

//set options
curl_setopt_array($curl, $options);
// request
$result = curl_exec($curl);

echo $result;

HTTPのレスポンスが見たい

<?php
// request
$result = curl_exec($curl);
//リクエストに関する情報
$info   = curl_getinfo($curl);

curl_getinfo の結果は配列

Array (
    [url] => http://localhost/
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 363
    [request_size] => 48
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.001496
    [namelookup_time] => 0.000795
    [connect_time] => 0.000931
    [pretransfer_time] => 0.000994
    [size_upload] => 0
    [size_download] => 44
    [speed_download] => 29411
    [speed_upload] => 0
    [download_content_length] => 44
    [upload_content_length] => 0
    [starttransfer_time] => 0.001446
    [redirect_time] => 0
    [redirect_url] =>
    [primary_ip] => ::1
    [certinfo] => Array
        (
        )

    [primary_port] => 80
    [local_ip] => ::1
    [local_port] => 50279
)

ターミナルから実行した時にcurl コマンドのオプションで、取得できる情報と同じものが取れる。

転送速度や接続時間とか便利そうです。

レスポンスヘッダも見たい

オプションをつかうことで、 HTTP のレスポンスヘッダを付加された、ナマのHTTPレスポンスを見ることが出来る。

<?php
//
$url = "http://localhost";
//
$curl = curl_init($url);
//
$options = array();
$options[CURLOPT_HEADER] = true;//実行結果取得
//
curl_setopt_array($curl, $options);
//
$result = curl_exec($curl);

実行結果

takuya@rena:~/Desktop$ php test.php

HTTP/1.1 200 OK
Date: Sun, 27 Jul 2014 00:22:51 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Content-Location: index.html.en
Vary: negotiate
TCN: choice
Last-Modified: Fri, 17 Jan 2014 16:20:28 GMT
ETag: "3f59f-2c-4f02ceb8dab00"
Accept-Ranges: bytes
Content-Length: 44
Content-Type: text/html
Content-Language: en

<html><body><h1>It works!</h1></body></html>

綺麗にHTTPのレスポンスヘッダを含めた、HTTPのレスポンスを見られる、これは便利。

レスポンスヘッダと、レスポンスボディを分割したい。 全部取れると便利だったり不便だったりするので、情報を分割したい。

<?php
//リクエスト
$result = curl_exec($curl);

//リクエスト実行後
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($result, 0, $header_size);
$body = substr($result, $header_size);

curl 扱えると多分安心

cURLを扱えると、ネットワークにアクセスするプログラムは殆どcURLで扱えるので、嵌り込むことが少なそう。ただしユーザーが少ないので、もっと情報がほしいなと思ったりす。

sshftp や ftps など、各種プロトコルも扱える。

もうライブラリさがしたり、fopen_wrapperに頼らなくていいんですね。

参考資料

http://jp1.php.net/manual/ja/function.curl-setopt.php

2018-12-10

誤字修正

2019-03-02

JSON をBodyに入れてリクエストを投げるときの記述を追加