cURLを使ってみた

#はじめに
案件で外部APIのシステムにアクセスするためのcURLのコードを書いたので、合わせて今まで書いたことがなかったのでcURLの使い方をメモしておきます。

#使い方
##基本的な関数は4つ 
1. `curl_init($URL)` 
 - cURLのセッションを初期化する。引数にはリクエスト先のURLを渡してあげるます。  
2. `curl_setopt()` 
 - 転送用の様々なオプションを設定することができる(例: CURLOPT_POST←POSTメソッドで送信する)
3. `curl_exec()`
 - curl_exec — cURL セッションを実行する
4. `curl_close()`
 - cURL セッションを閉じる

##基本的な関数の使い方
以下が簡単な使い方である

```php:cUrl.php 
<?php
$url = 'http://*****.com';
// セッションの初期化 $chにはcURLハンドルが格納される。 
$ch = curl_init($url);

// 転送用の様々なオプションを設定
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);

// cURLの実行とレスポンスを変数に格納
$res = curl_exec();
 
// cURLのセッションを終了する
curl_close($ch);

// レスポンスを返却する
return $res;

```

基本的には上記のようcURL セッションハンドルを初期化して、様々なオプションを設定後cURL セッションハンドルを実行し、セッションを終了する
という流れで使用できます。

##様々なオプションについて
オプションの種類は数多くあります。全てをここに記述することはPHPのリファレンスに記述されているため記載しません。[PHPリファレンス](https://www.php.net/manual/ja/function.curl-setopt.php)
使う頻度が高そうなものだけに絞って記載いたします。
オプションはCURLOPT_*****という定数で設定をすることができます。 

- CURLOPT_HTTPHEADER
 - 設定する HTTP ヘッダフィールド。配列で複数のヘッダー情報を設定することができます。
- CURLOPT_POST
 - HTTP POSTメソッドでリクエストする時に`TRUE`を設定して使用します。
- CURLOPT_POSTFIELDS
 - POSTで送信する際のデータを設定することができます。
 - `para1=val1&para2=val2&...` のように url エンコードされた文字列形式または配列で設定することができます。
 - 何をPOSTデータとして送信するかによるが、もしContent-Typeが`application/x-www-form-urlencoded;`だった場合は必ずエンコードしなければ正しく動作しません。
- CURLOPT_RETURNTRANSFER
 - レスポンス内容を文字列として扱う場合、`TRUEを設定して使用する。
 - 設定しない場合は、レスポンス内容を出力するだけとなってしまう。
 - APIの場合はレスポンスのデータをあれこれ使用するためにcURLを使用すると思いますのでこの設定は必須だと思います。
- CURLOPT_CONNECTTIMEOUT
 - 接続の試行を待ち続ける秒数。0 は永遠に待ち続けることを意味します。
 - デフォルトは0なので、設定しない場合永遠に待ち続けることになるので、注意  
上記は基本的に設定することが多いと思われるオプションになるかと思います。
あとは、UserAgentやAPIならAccessKeyの設定など、必要なものを設定すればいいので、その都度[PHPリファレンス](https://www.php.net/manual/ja/function.curl-setopt.php)を参照すれば良いです。

##様々なオプションの設定方法
```php:cUrlOption.php
<?php
$url = 'http://*****.com';
$accessKey = ******;
// セッションの初期化 $chにはcURLハンドルが格納される。 
$ch = curl_init($url);

// 転送用の様々なオプションを設定
$headers = [
               'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
               'Authorization: Bearer ' . $accessKey;
           ];
$params = [
            'name' => 'bellcrud'
          ];
// 以下オプションの設定
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
// Content-Typeがapplication/x-www-form-urlencoded;なので変数はエンコードしてあげる
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

// cURLセッションハンドラの実行
$response = curl_exec($ch);

// cURLセッションを削除
curl_close($ch);

// APIの返却値がjson形式なら適切な PHPが扱いやすいようにデコードする
return json_decode($response);

``` 
オプションの設定する際に配列にすることで一括でオプションを設定できるようにすることが可能です。
行数では若干増えますが、見やすさでは配列の方が個人的に見やすいので、配列で一括設定する方法を私はおすすめします。

```php:cUrlOption2.php
<?php
$url = 'http://*****.com';
$accessKey = ******;
// セッションの初期化 $chにはcURLハンドルが格納される。 
$ch = curl_init($url);

// 転送用の様々なオプションを設定
$headers = [
               'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
               'Authorization: Bearer ' . $accessKey;
           ];
$params = [
            'name' => 'bellcrud'
          ];
// 以下オプションを配列を使用して一括で設定
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER, true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS, http_build_query($params),
    CURLOPT_HTTPHEADER, $headers,
    CURLOPT_TIMEOUT, 10
]);

// cURLセッションハンドラの実行
$response = curl_exec($ch);

// cURLセッションを削除
curl_close($ch);

// APIの返却値がjson形式なら適切な PHPが扱いやすいようにデコードする
return json_decode($response);
```

##注意事項
ヘッダー情報やPOSTメソッドでのデータ送信で詰まってしまうことがあります。
様々なオプションを設定の項目で書きましたが、CURLOPT_POSTFIELDSはContet-Typeと辻褄が合うように設定できているか今一度確認し直しましょう！
私はここで、詰まりました。私のように初心者の方は特に！

##詰まった時の確認方法記載リンク(他者のページ)
[PHP の cURL 実際にリクエストされたヘッダを確認する方法](http://cl.pocari.org/2009-02-16-1.html)
[【php】送信したリクエストの内容を見る方法（1）](https://www.softel.co.jp/blogs/tech/archives/5822)
[【php】送信したリクエストの内容を見る方法（2）](https://www.softel.co.jp/blogs/tech/archives/5823)