Socket(ソケット)でデータを送信・受信 - fsockopen、POST、GET
更新:2008-12-14
PHPでは、fsockopen() を使って、Socket(ソケット)の処理を行なう。 リクエストする各値は、\n ではなく \r\n で改行を行なう。 POSTやGETで渡す値は、リクエストヘッダの後、2回改行後、付け加える。
サンプルは、HTTP/1.1だが、HTTP/1.0でも基本的に書き方は同じ。 HTTP/1.1の場合は、Connection: Close がないと接続を維持するため、応答が遅くなる。 1回のリクエスト後、即接続を終了したい場合は、Connection: Close を書く。 フォームのデータを送信する場合は、Content-Type: application/x-www-form-urlencoded 。 以下サンプル。
//URLからホスト名、パス、クエリを取得
//$host = "www.sample.com";
//$path = "/data/sample.php?a=12";
$target_url = "http://www.sample.com/data/sample.php?a=12";
$url_array = parse_url($target_url);
$port = 80;
if(isset($url_array['query'])){
$query = "?" . $url_array['query'];
}
$host = $url_array['host'];
$path = $url_array['path'] . $query;
if($path === ""){
$path = "/";
}
$params = "name=" . urlencode("名前")
. "&title=" . urlencode("タイトル")
. "&useragent=" . $_SERVER['HTTP_USER_AGENT'];
$results = send_socket($host, $port, $path, $params);
echo $results;
//送信関数
function send_socket($host, $port, $path, $param){
$data = '';
$sock = fsockopen($host, $port);
$request = "POST " . $path . " HTTP/1.1\r\n"
. "Host: " . $host . "\r\n"
. "Content-Type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($param) . "\r\n"
. "User-Agent: MSIE7.0\r\n"
. "Connection: Close\r\n"
. "\r\n"
. $param . "\r\n";
if(!$sock){
$data = 'socket error:' . $host;
}else{
fputs($sock, $request);
while(!feof($sock)){
$data .= fgets($sock);
}
fclose($sock);
}
return $data;
}
上記 $params は、http_build_query() を使って以下のように書ける。
$params = array('name' => urlencode("名前"),
'title' => urlencode("タイトル"),
'useragent' => $_SERVER['HTTP_USER_AGENT'],
);
$results = send_socket($host, $port, $path, http_build_query($params));
PING送信
ブログなどでよく使われるPINGサーバへのPINGの送信は、上記サンプルで $request の部分を以下のようにする。
$request = "POST " . $path . " HTTP/1.1\r\n" . "Host: " . $host . "\r\n" . "Content-Type: text/xml\r\n" . "Content-Length: " . strlen($param) . "\r\n" . "User-Agent: MSIE7.0\r\n" . "Connection: Close\r\n" . "\r\n" . $param . "\r\n";
また、送信するデータ $params は以下の書式。
$params = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" . "<methodCall>\r\n" . "<methodName>weblogUpdates.ping</methodName>\r\n" . "<params>\r\n" . "<param><value>自分のサイトのタイトル</value></param>\r\n" . "<param><value>自分のサイトのURL</value></param>\r\n" . "</params>\r\n" . "</methodCall>";