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

この記事からわかること

  • cURLの概要とメリット
  • cURLの使い方と流れ
  • オプション関数の種類

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

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の使用流れ

  1. cURLセッションの初期化
  2. cURL転送用オプションの設定
  3. cURLセッションの実行
  4. 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);

⇩⇩⇩⇩結果⇩⇩⇩⇩

webエンジニア学習部屋

CURLOPT_RETURNTRANSFERで文字として取得

転送用オプションのところでCURLOPT_RETURNTRANSFERtrueにすることで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);

⇩⇩⇩⇩結果⇩⇩⇩⇩

cURLで文字列として出力させたWebエンジニア学習部屋

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_VERIFYPEERfalseにすることで取得が可能になります。

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パターンの時のエスケープ処理方法を紹介します。

  1. URL自体が存在しない
  2. ホストはドメインは存在するがページが存在しない

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);

⇩⇩⇩⇩結果⇩⇩⇩⇩

webエンジニア学習部屋の404ページをcURLで取得

つまりページが存在しない(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_POSTtrueを指定することでPOSTの使用を可能にできます。CURLOPT_POSTFIELDS引数にデータを渡すことで実際にPOSTすることができます。

実際に渡せているか確認してみましょう!例えば取得するサイトにこのようなコードを追加しておきます。

<p><?php echo $_POST['cURL'];?></p>

今回はこのサイトで実践してみます。まずはトップページのindex.phpに上記のコードを記述します。

トップページに組み込まれたコード

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

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); // ドキュメントの取得にかかった時間

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index