サンプル・プログラムの実行例
サンプル・プログラム
curl_ssl.php | サンプル・プログラム本体。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「PHPでGET/POSTでフォームから値を受け取る」「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
PHPでSSL通信を行う方法
SSL通信の場合、具体的にはOpenSSLがインストールされている必要がある。PHP5以降ではモジュール組み込みが可能だが、PHP 4.3.0以降では静的にコンパイルされ組み込まれている必要がある。このため、レンタルサーバなどリコンパイルが望めない環境では利用できない。
そこで今回は、PHP4.xでもモジュールを追加するだけでSSL通信が可能になるcURL, Client URL Library 関数を利用することにする。
cURL関数の準備
libcurl は現在、http, https, ftp, gopher, telnet, dict, file, ldap プロトコルをサポートしている。
cURL関数を利用するには、--with-curl[=DIR] を付けて PHP をコンパイルしておく。ここで、DIR は、ディレクトリ lib および include を有するディレクトリの場所である。
ディレクトリ "include" には、"curl" という名前のフォルダがある必要があり、そのフォルダにはファイル easy.h および curl.h がある必要がある。また、libcurl.a という名前のファイルがディレクトリ "lib" にある必要がある。
PHP 4.3.0 以降では、URL ストリームで cURL を使用するよう PHP を 設定するために --with-curlwrappers を指定できるようになった。
Windows環境では、libeay32.dll および ssleay32.dll を PATH の通ったディレクトリ(一般的に \windows\system32\)に配置する必要がある。これらの dll はPHPのパッケージの dlls に含まれている。
次に、php.ini の extension=php_curl を有効にする。
PHPを再起動すれば、cURL関数群が利用できるようになる。
解説:SSLサイトからテキストを取得
107: /**
108: * SSLサイトからテキストを取得
109: * @param string $url サイトURL
110: * @param string $errmsg エラーメッセージ
111: * @return string テキスト
112: */
113: function getSSLsite($url, &$errmsg) {
114: //SSLが利用できるかどうか調べる
115: $arr = stream_get_transports();
116: $errmsg = 'PHP処理系がSSL通信に対応していない';
117: foreach ($arr as $val) {
118: if (preg_match('/ssl/i', $val) > 0) {
119: $errmsg = '';
120: break;
121: }
122: }
123: if ($errmsg != '') return FALSE;
124:
125: //cURL関数が利用できるかどうか調べる
126: $errmsg = 'PHP処理系がcURL関数に対応していない';
127: if (function_exists('curl_init')) {
128: $errmsg = '';
129: }
130: if ($errmsg != '') return FALSE;
131:
132: //SSLサイトからテキストを取得
133: $curl = curl_init($url);
134: // curl_setopt($curl, CURLOPT_SSLVERSION, 3); //SSLv3脆弱性対応
135: curl_setopt($curl, CURLOPT_URL, $url);
136: curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //結果を文字列で返す
137: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); //サーバ証明書検証をスキップ
138: curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 同上
139: curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE); //リダイレクトをたどる
140: curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE); // 同上
141: curl_setopt($curl, CURLOPT_TIMEOUT, 30); //タイムアウト時間
142:
143: $result = curl_exec($curl);
144: curl_close($curl);
145:
146: //取得テキストを加工
147: $str = strip_tags($result);
148: $outstr = "";
149: $tok = strtok($str, "\n");
150: while ($tok != FALSE) {
151: $ss = trim($tok);
152: if ($ss != '') {
153: $outstr .= $tok . '<br />';
154: }
155: $tok = strtok("\n");
156: }
157:
158: return $outstr;
159: }
まず、PHP処理系がSSL通信に対応しているかどうか、組み込み関数 stream_get_transports を使って調べる。
次に、PHP処理系がcURL関数をサポートしているかどうか、組み込み関数 function_exists を使って調べる。
cURL関数の使い方は簡単である。
まず、関数 curl_init を使って cURL セッションを初期化する。戻り値はリソースIDである。
次に、関数 curl_setopt を使って、通信用の各種オプションを設定していく。
一般的には、CURLOPT_URL,CURLOPT_RETURNTRANSFER の2つを指定する。
サーバ証明書の検証を求めてくるようなサイトに対しては、これをスキップするため、CURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST の2つをFALSEにする。
なお、CURLOPT_SSLVERSIONについてはSSLv2、SSLv3の既知の脆弱性に対応するため、指定を行わない方が無難だ。
関数 curl_exec によってSSL通信を実施し、戻ってきたテキスト(サイト・コンテンツ)$result からHTMLタグや余分な改行を除き、変数 $outstr に格納して戻す。
WebAPIとSSL通信
cURL関数は GET/POST 渡しを行うことも簡単にできる。
また、戻り値のXMLは、DOM XML関数を使うか、SimpleXMLで処理するなら関数 simplexml_load_string で $result を取り込めばいいだろう。
今回は、PHPでSSL通信を行う方法を紹介する。
(2022年6月27日)FastCGIで正常動作しない不具合を修正
(2022年5月21日)大幅改訂,SSL検証サイト変更,PHP8対応