PHPでPOST送信まとめ



PHPでのPOST送信には大まかに以下の様な4パターンほどの方法があります。

- file_get_contents
- fopen
- fsockopen
- curl

ただし、**fopen**に関しては**file_get_contents**とほぼ同じ様な処理なので、こういった方法もあるという参考程度にしてください。
簡単な送信であれば**file_get_contents**を使う方法がベターです。
通信量が多い場合や、重い処理の場合は**cURL**を使うと良いです。

### file_get_contentsを使った方法

```php

    $url = 'http://cppe.hol.es/post.php';
    
    $data = array(
        'msg' => 'メッセージ',
    );
    
    $context = array(
        'http' => array(
            'method'  => 'POST',
            'header'  => implode("\r\n", array('Content-Type: application/x-www-form-urlencoded',)),
            'content' => http_build_query($data)
        )
    );
    
    $html = file_get_contents($url, false, stream_context_create($context));
    
    //var_dump($http_response_header);
    
    echo $html;
    
```

file_get_contentsのステータスを確認する場合は「$http_response_header」を使うとアクセスしたURLのレスポンスヘッダを確認することが出来ます。


### fopenを使った方法
```php
    $url = 'http://cppe.hol.es/post.php';
    
    $data = array(
        'msg' => 'メッセージ',
    );
    
    $context = array(
        'http' => array(
            'method'  => 'POST',
            'header'  => implode("\r\n", array('Content-Type: application/x-www-form-urlencoded',)),
            'content' => http_build_query($data)
        )
    );
    
    $fp = fopen($url, 'r', false, stream_context_create($context));
    $header = stream_get_meta_data($fp);
    $html = stream_get_contents($fp);
    fclose($fp);
    
    //var_dump($header);
    echo $html;
```

fopenとfile_get_contentsの違いはstream_get_contentsを使っています。この関数はオープンしている ストリームリソースに対しての操作だそうです。

### fsockopenを使った方法

```php
    
    $fp = fsockopen('XXX.XXX.XX.XX', 8080);
     
    $data = array(
        'msg' => 'メッセージ',
    );

    $data = http_build_query($data);

    $request = array(
        'POST /post.php HTTP/1.1',
        'Host: cppe.hol.es',
        'Content-type: application/x-www-form-urlencoded',
        'Content-length: ' . strlen($data) . '',
    );
     
     
    fwrite($fp, implode($request, "\r\n") . "\r\n\r\n" . $data);
    while($contents = fread($fp, 1024)){
        $response .= $contents;
    }
    fclose($fp);
     
    $response = explode("\r\n\r\n", $response);
    $header = $response[0];
    $html = $response[1];
     
    //echo $header;
    echo $html;

```

### curlを使った方法
```php

    $CURLERR = NULL;
    
    $data = array(
        'msg' => 'メッセージ',
    );
    
    $url = 'http://cppe.hol.es/post.php';
    
    $ch = curl_init($url);
    
    curl_setopt($ch, CURLOPT_POST, TRUE);                            //POSTで送信
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));    //データをセット
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);                    //受け取ったデータを変数に
    $html = curl_exec($ch);
    
    if(curl_errno($ch)){        //curlでエラー発生
        $CURLERR .= 'curl_errno：' . curl_errno($ch) . "\n";
        $CURLERR .= 'curl_error：' . curl_error($ch) . "\n";
        $CURLERR .= '▼curl_getinfo' . "\n";
        foreach(curl_getinfo($ch) as $key => $val){
            $CURLERR .= '■' . $key . '：' . $val . "\n";
        }
        echo nl2br($CURLERR);
    }
    curl_close($ch);
    echo $html;
```

curlを使った処理の方がfile_get_contentsを使うよりも高速かつ、エラー処理がしやすいようです。


## まとめ
file_get_contentsを使った方法を解説しているサイトも多いですが、curlのほうがオプションが豊富で、マルチスレッドで動かす方法もあったりするので、覚えるならこちらの方が何かと便利です。

参考サイト
- [PHP: HTTP コンテキストオプション - Manual](http://php.net/manual/ja/context.http.php)
- [PHP: file_get_contents - Manual](http://php.net/manual/ja/function.file-get-contents.php)
- [http://php.net/manual/ja/function.fsockopen.php](PHP: fsockopen - Manual)
- [PHP: cURL - Manual](http://php.net/manual/ja/book.curl.php)
- [【php】fsockopen()関数でhttpのGETリクエストを送信する at softelメモ](https://www.softel.co.jp/blogs/tech/archives/2126)