cURLの挙動について

PHPcURLを使う時のCURLINFO_HEADER_OUTとCURLOPT_VERBOSEの挙動についてのメモ。

とりあえず最低限のオプションのみで実行してみる。

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

echo '<pre>';
print_r(curl_getinfo($ch));
?>

送信ヘッダの取得は出来ない
Array
(
    [url] => http://www.google.co.jp/
    [content_type] => text/html; charset=Shift_JIS
    [http_code] => 200
    [header_size] => 609
    [request_size] => 55
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.17429
    [namelookup_time] => 0.019786
    [connect_time] => 0.058394
    [pretransfer_time] => 0.058422
    [size_upload] => 0
    [size_download] => 29089
    [speed_download] => 166899
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.102573
    [redirect_time] => 0
)

次にCURLINFO_HEADER_OUTをtrueに設定し、再度実行

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ch);

echo '<pre>';
print_r(curl_getinfo($ch));
?>

正常に送信ヘッダの取得は出来た。

Array
(
    [url] => http://www.google.co.jp/
    [content_type] => text/html; charset=Shift_JIS
    [http_code] => 200
    [header_size] => 609
    [request_size] => 55
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.169215
    [namelookup_time] => 0.019161
    [connect_time] => 0.056915
    [pretransfer_time] => 0.056952
    [size_upload] => 0
    [size_download] => 28910
    [speed_download] => 170847
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.099661
    [redirect_time] => 0
    [request_header] => GET / HTTP/1.1
Host: www.google.co.jp
Accept: */*


)

次にCURLOPT_VERBOSEだけを有効にしてみる

<?php
$fp = tmpfile();

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $fp);
$response = curl_exec($ch);

echo '<pre>';
print_r(curl_getinfo($ch));

fseek($fp, 0);
$verbose = '';
while (($line = fgets($fp)) !== false) {
    $verbose .= $line;
}
fclose($fp);

echo $verbose;
?>

リクエストの詳細の取得は正常に出来た、詳細には送信・受信ヘッダ共に記述されている。

Array
(
    [url] => http://www.google.co.jp/
    [content_type] => text/html; charset=Shift_JIS
    [http_code] => 200
    [header_size] => 609
    [request_size] => 55
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.174437
    [namelookup_time] => 0.017929
    [connect_time] => 0.056555
    [pretransfer_time] => 0.056586
    [size_upload] => 0
    [size_download] => 29107
    [speed_download] => 166862
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.101525
    [redirect_time] => 0
)
* About to connect() to www.google.co.jp port 80
*   Trying 64.233.183.106... * connected
* Connected to www.google.co.jp (64.233.183.106) port 80
> GET / HTTP/1.1
Host: www.google.co.jp
Accept: */*

< HTTP/1.1 200 OK
< Date: Thu, 28 Jul 2011 11:40:11 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=Shift_JIS
< Set-Cookie: PREF=ID=f594bcbff899f3b1:FF=0:TM=1311853211:LM=1311853211:S=I6qM4ZKHRVYZOZ4_; expires=Sat, 27-Jul-2013 11:40:11 GMT; path=/; domain=.google.co.jp
< Set-Cookie: NID=49=n-u1vQyrvh8AEIaqRZAgHDdPIHnpkhcADuAyIngubbzP3aPNranWFSvBih4eABLZTaucHxVoLWnec_avcsWfjg0mE7ZOmK904Ne7-J7wwMPHhkQqV6Og8UTL1MS4KJra; expires=Fri, 27-Jan-2012 11:40:11 GMT; path=/; domain=.google.co.jp; HttpOnly
< Server: gws
< X-XSS-Protection: 1; mode=block
< Transfer-Encoding: chunked
* Connection #0 to host www.google.co.jp left intact

次にこの状態で、CURLINFO_HEADER_OUTを有効にしてみる

<?php
$fp = tmpfile();

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.co.jp/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $fp);
$response = curl_exec($ch);

echo '<pre>';
print_r(curl_getinfo($ch));

fseek($fp, 0);
$verbose = '';
while (($line = fgets($fp)) !== false) {
    $verbose .= $line;
}
fclose($fp);

echo $verbose;
?>

CURLINFO_HEADER_OUTが優先されて、リクエストの詳細は取得出来なかった。
ちなみにCURLINFO_HEADER_OUTをCURLOPT_VERBOSEより下に移動してもダメだったので、CURLINFO_HEADER_OUTが設定されると
CURLOPT_VERBOSEは強制的に無効になるようだ。

Array
(
    [url] => http://www.google.co.jp/
    [content_type] => text/html; charset=Shift_JIS
    [http_code] => 200
    [header_size] => 609
    [request_size] => 55
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.17543
    [namelookup_time] => 0.016662
    [connect_time] => 0.056478
    [pretransfer_time] => 0.056505
    [size_upload] => 0
    [size_download] => 28910
    [speed_download] => 164795
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.101421
    [redirect_time] => 0
    [request_header] => GET / HTTP/1.1
Host: www.google.co.jp
Accept: */*


)

ちなみに、CURLOPT_VERBOSEは有効にしたくないけど、受信・送信ヘッダ共に取得したい場合は
CURLOPT_HEADERを有効にして、レスポンス(ボディ部含む)からヘッダとボディを分割するしかないっぽい