【PHP】cURLとは?メリットと使い方、オプションをまとめて解説!

この記事からわかること
- cURLの概要とメリット
- cURLの使い方と流れ
- オプション関数の種類
index
[open]
\ アプリをリリースしました /
cURL(カール)とは
cURL(カール)とはClient URL Libraryの略称で外部サイトの情報を取得できるPHPの拡張機能の1つです。
外部サイトの情報を取得するのはfile_get_contents関数
でも実行可能です。
ですがfile_get_contents関数ではなくcURLを使うことでHTTP通信でのリクエストやレスポンス、ヘッダ情報を操作しやすくなります。
Webページはそもそもクライアント(ユーザー)側からのリクエストに基づいてサーバ側のレスポンスを返すことで正常に表示されています。
リクエストには要求しているページURLやGET/POSTなどのフォームから送信されたデータ、クライアントの情報などが「リクエストヘッダ」という場所にまとまって送信されます。
クライアントのリクエストを受けたサーバーは処理後にレスポンスを返します。 レスポンスの中にはサーバでの処理結果を表すHTTPステータスやサーバ情報などが格納されたレスポンスヘッダ、そして求めたページ情報などが含まれています。
それらのヘッダ情報をカスタマイズすることで外部サイトに対してGET/POSTを送信したり、出力されているHTMLを取得したりすることができます。
cURLの使い方と流れ
cURLを使うには流れに沿ってコードを記述しないといけません。
cURLの使用流れ
- cURLセッションの初期化
- cURL転送用オプションの設定
- cURLセッションの実行
- cURLセッションの終了
cURLセッションの初期化
最初にcURLを初期化します。これからセッション(接続)するのでその前に一度真っ新にするイメージでしょうか。関数のinitはinitialize(初期化)のinitですね!
$ch = curl_init($url);
この関数は戻り値としてリソース型(PHPのデータ型の1つ)のcURLを操作できるハンドルを返します。(cURLのハンドルで$chです)このハンドルに対してオプション設定や実行処理をかけていきます。
引数にはセッションを開始したいURLを指定できます。ここでURLを指定した値は後述するオプション設定のCURLOPT_URL
の値が設定されます。省略も可能で省略する場合はオプション設定の際にCURLOPT_URL
を指定します。
cURL転送用オプションの設定
次に転送用オプションを設定していきます。初期化の際にURLを指定しなかった場合はここでURLをしてします。
オプションを設定するのはcurl_setopt関数
の役割です。第1引数にcURLハンドラ、第2引数にCURLOPT_XXXXXという設定項目、第3引数に設定項目ごとの値をセットします。
curl_setopt($ch, CURLOPT_URL, $url); // initで引数を指定しなかった場合
curl_setopt($ch, CURLOPT_FAILONERROR, true); // HTTPステータスが400以上なら処理失敗と判断
公式マニュアル:cURL転送オプション一覧
cURLセッションの実行
オプションの設定が完了したら実際にセッションを実行させます。
指定したURLが存在しないなど処理が失敗するとcurl_exec関数
は戻り値としてfalse
を返します。
$html = curl_exec($ch);
cURLセッションの終了
処理が終了したら$ch
に格納されていたリソース型のcURLハンドラを解放しておきます。使い終わったら予期せぬ使い方をされぬように後片付けをするのが基本です。
curl_close($ch);
var_dump
で表示させてみるとリソース型という型式はそのままですがtypeが未定義になっていることが確認できます。
$ch = curl_init($url);
var_dump($ch); // 結果:resource(2) of type (curl)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
curl_close($ch);
var_dump($ch); // 結果:resource(2) of type (Unknown)
実際の使い方
実際にページを取得するコードを記述してみます。今回取得するのはこのサイトのトップページです。適当なPHPファイルを作成してこのコードを記述するだけでトップページを取得することができます。
以下のコードの細かいところは後述していきます。
$url = "http://tech.amefure.com/";
//cURLセッションを初期化
$ch = curl_init();
//URLとオプションを指定
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // SSL化されているサイトも取得可能にする
curl_setopt($ch, CURLOPT_FAILONERROR, true); // HTTPステータスが400以上なら処理失敗と判断
//セッションを実行
$html = curl_exec($ch);
// ページに出力
if($html){
echo $html;
}else{
echo "サイトが見つかりませんでした";
}
//セッションを終了
curl_close($ch);
⇩⇩⇩⇩結果⇩⇩⇩⇩

CURLOPT_RETURNTRANSFERで文字として取得
転送用オプションのところでCURLOPT_RETURNTRANSFER
をtrue
にすることでwebページを文字列として取得することができます。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
この設定をしない場合はデータが直接出力されますが、trueにすることで文字として出力されるのでhtmlのエスケープ処理を行えるhtmlspecialchars関数
と組み合わせればコードを表示させることができます。
$url = "http://tech.amefure.com/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 文字列として出力
$html = curl_exec($ch);
$html = htmlspecialchars($html,ENT_QUOTES | ENT_HTML5,'UTF-8');
echo $html;
curl_close($ch);
⇩⇩⇩⇩結果⇩⇩⇩⇩

HTTPS(SSL化)サイトの取得方法
Webサイトの通信を暗号化し、盗聴や改ざんを防ぐことができるSSL通信(Secure Socket Layer)。サイトにSSLを導入しているとURLの先頭部分が「http://〜」ではなく「https://〜」となります。
cURLでは通常HTTP通信での取得を行うため「https://〜」から始まるサイトを取得できないことがあります。
私が別でWordPressを使って別で運営している楽器サイト(https://www.amefure.com)もSSL化してあり「http://〜」でアクセスされた時には「https://〜」にリダイレクトされるようになっているのでこのままではcURLが使えませんでした。
その場合はオプション設定でCURLOPT_SSL_VERIFYPEER
をfalse
にすることで取得が可能になります。
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // SSL化されているサイトも取得可能にする
SSL化したサイトを使い、リダイレクト設定などでcURLで取得できない場合はこの方法を試してみてください!
ローカル環境のサイトも取得
MAMPなどでローカル環境でテスト運用している範囲であればローカルサイトも取得可能です。あくまでテスト環境ですのでこのコードをサーバーにアップしても使えるわけではありませんので注意してください。
$url = "http://localhost/"; // ローカルでもOK
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$html = curl_exec($ch);
// エスケープ処理
if($html){
echo $html;
}else{
echo "サイトが見つかりませんでした";
}
curl_close($ch);
cURLはサーバーにアップしなくても挙動を確認できるのでぜひ色々試してみてください。
サイトに正しく接続するためのエスケープ処理
cURLでサイト情報を取得する時も失敗した時に予期せぬ挙動を起こしてしまわないようにエスケープ処理を適切に施すことが大切です。
今回は以下の2パターンの時のエスケープ処理方法を紹介します。
- URL自体が存在しない
- ホストはドメインは存在するがページが存在しない
URLが存在しない場合
例えばこのように存在しないURLを指定した時や昔はあっても時と共にサイトが消えてしまった時にコードがそのままではエラーが起きなくとも戻り値が何もなくcURLに基づいたコードは予期せぬ挙動を起こしてしまうかもしれません。
$url = "http://mechakutya.ccoomm";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$html = curl_exec($ch);
// エスケープ処理
if($html){
echo $html;
}else{
echo "サイトが見つかりませんでした";
}
curl_close($ch);
その際には処理が失敗するとfalse
を返すcurl_exec関数
をキーに処理を分岐させると安心です。
CURLOPT_FAILONERRORでHTTPステータスで分岐
サイト自体は存在するけれどページが存在しない場合は少し挙動が変わってきます。
cURLでは指定したURLのHTTPステータスが何であれ取得してくれます。HTTPステータスとはクライアント側から送信したリクエストに対してのサーバ側の処理結果を数値で表したものです。
HTTPステータス
ステータス | 意味 |
---|---|
200 | 成功 |
302 | リダイレクト |
404 | リソースが見つからない |
500 | サーバーエラー |
例えばcURLでこのサイトの存在しないページを取得しようとすると404ページ(Not Found)を取得することになります。
$url = "http://tech.amefure.com/存在しないページ";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$html = curl_exec($ch);
echo $html;
curl_close($ch);
⇩⇩⇩⇩結果⇩⇩⇩⇩

つまりページが存在しない(404)でもサーバーエラー(500)でもそのエラーページを取得してくれるのです。
通常に成功した時のみページ情報が欲しい場合はオプションにCURLOPT_FAILONERROR
を設定すると簡単に変更することができます。
curl_setopt($ch, CURLOPT_FAILONERROR, true); // HTTPステータスが400以上なら処理失敗と判断
この設定をすることでHTTPステータスが400以上の場合(エラーの場合)は処理失敗と判断してくれます。すると先ほどのcurl_exec関数
はfalse
を返すのでそのままエスケープさせることができるのです。
POSTデータを送信する
cURLでは取得しているサイトにPOSTデータを送信することもできます。POSTデータはPHPのスーパーグローバル変数$_POST
で扱えるリクエスト情報の1つでHTMLのフォーム要素から送信された値を取得、操作する時によく使われます。
実際のコードは以下のような感じです。
$url = "http://localhost/";
// POSTデータを格納
$post = ["cURL" => "cURLで取得された場合に表示されるよ"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// POST用の設定オプション
curl_setopt($ch, CURLOPT_POST, true); // POST通信を可能にする
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); // POSTにデータを渡す
$html = curl_exec($ch);
echo $html;
curl_close($ch);
CURLOPT_POST
にtrue
を指定することでPOSTの使用を可能にできます。CURLOPT_POSTFIELDS
の引数にデータを渡すことで実際にPOSTすることができます。
実際に渡せているか確認してみましょう!例えば取得するサイトにこのようなコードを追加しておきます。
<p><?php echo $_POST['cURL'];?></p>
今回はこのサイトで実践してみます。まずはトップページのindex.phpに上記のコードを記述します。

その後に適当なphpファイルを作成し先ほどのcURL接続のコードを記述すると・・・

通常にアクセスした場合は何も表示されませんが、cURLで取得して表示させた場合にはしっかり表示されるようになりました。
cURL接続時のみ表示や挙動を変更できそうなので色々なことに使えそうですね!
cURL接続情報を取得する方法
cURLで接続した時の情報はcurl_getinfo関数で取得することができます。
curl_getinfo($ch, オプション名);
取得できるのはHTTPステータスコードやIPアドレス、ドキュメントの取得にかかった時間やヘッダのサイズなど様々です。
echo curl_getinfo($ch,CURLINFO_HTTP_CODE); // HTTPステータスコード
echo curl_getinfo($ch,CURLINFO_PRIMARY_IP); // IPアドレス
echo curl_getinfo($ch,CURLINFO_FILETIME); // ドキュメントの取得にかかった時間
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。