在ubuntu系統中 curl必須安裝 php5-curl
除了curl還有另一種方法,使用fsockopen()
測試API接口
http://test.localhost/PHP/wget_server.php
echo json_encode($_REQUEST);
stackoverflow的範例
// http://stackoverflow.com/questions/2367458/php-post-data-with-fsockopen $fp = fsockopen('test.localhost', 80); // 必須寫 test.localhost。不能加protocol、位址和參數 http://test.localhost/PHP/wget_server.php?bear=2 // post的資料 $vars = array( 'hello' => 'world', 'bear' => 123 ); $content = http_build_query($vars); // $content:hello=world&bear=123 fputs($fp, "POST /PHP/wget_server.php?bear=2 HTTP/1.1\r\n"); // 位址和參數寫在這,使用POST fputs($fp, "Host: test.localhost\r\n"); //再寫一次host fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); fputs($fp, "Content-Length: ".strlen($content)."\r\n"); fputs($fp, "Connection: close\r\n"); fputs($fp, "Referer: https://www.google.com.tw/?gws_rd=ssl\r\n"); //偽造 $_SERVER['HTTP_REFERER'] fputs($fp, "Cookie: test=456;ai=789\r\n"); // 設定$_COOKIE fputs($fp, "\r\n"); fputs($fp, $content); header('Content-type: text/plain'); // 設定Content-Type為純文字 while (!feof($fp)) { echo fgets($fp, 1024); } fclose($fp);結果:
HTTP/1.1 200 OK Date: Wed, 28 Oct 2015 07:16:26 GMT Server: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8 X-Powered-By: PHP/5.6.8 Content-Length: 30 Connection: close Content-Type: text/html; charset=UTF-8 {"bear":"123","hello":"world"}$_SERVER['HTTP_REFERER']:https://www.google.com.tw/?gws_rd=ssl
$_COOKIE:Array
(
[test] => 456
[ai] => 789
)
說明:
Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
如果未指定 ContentType,默认为TEXT/HTML。
指令為text/plain 後,瀏覽器會直接顯示<tag>而不會視為HTML
blog.hsin.tw 的範例
//接收POST參數的URL $url = "http://test.localhost/PHP/wget_server.php?bear=2"; //POST參數,在這個陣列裡,索引是name,值是value,沒有限定組數 $postdata = array('post_name' => 'post_value', 'acc' => 'hsin', 'nick' => 'joe'); //函式回覆的值就是取得的內容 $result = sendpost($url, $postdata); echo "\$result:"; print_r($result); function sendpost($url, $data) { //先解析url 取得的資訊可以看看http://www.php.net/parse_url $url = parse_url($url); $url_port = $url['port'] == '' ? (($url['scheme'] == 'https') ? 443 : 80) : $url['port']; if (!$url) return "couldn't parse url"; echo "\$url_port:".$url_port; echo "\$url:"; print_r($url); //對要傳送的POST參數作處理 $encoded = ""; while (list($k, $v) = each($data)) { $encoded.= ($encoded ? '&' : ''); $encoded.= rawurlencode($k) . "=" . rawurlencode($v); } echo "$encoded:"; print_r($encoded); //開啟一個socket $fp = fsockopen($url['host'], $url_port); if (!$fp) return "Failed to open socket to " . $url['host']; //header的資訊 fputs($fp, 'POST ' . $url['path'] . ($url['query'] ? '?' . $url['query'] : '') . " HTTP/1.0\r\n"); fputs($fp, "Host: " . $url['host'] . "\n"); fputs($fp, "Content-type: application/x-www-form-urlencoded\n"); fputs($fp, "Content-length: " . strlen($encoded) . "\n"); fputs($fp, "Connection: close\n\n"); fputs($fp, $encoded . "\n"); //取得回應的內容 $line = fgets($fp, 1024); if (!eregi("^HTTP/1.. 200", $line)) return; $results = ""; $inheader = 1; while (!feof($fp)) { $line = fgets($fp, 2048); if ($inheader && ($line == "\n" || $line == "\r\n")) { $inheader = 0; } elseif (!$inheader) { $results.= $line; } } fclose($fp); return $results; }結果:
$url_port:80
$url:Array
(
[scheme] => http
[host] => test.localhost
[path] => /PHP/wget_server.php
[query] => bear=2
)
$encoded:post_name=post_value&acc=hsin&nick=joe
$result:{"bear":"2","post_name":"post_value","acc":"hsin","nick":"joe"}
說明:
該網站上的範例有誤,某些換行特殊符號忘記跳脫,如
應為
if($inheader&&($line == "\n" || $line == "\r\n")){
\r\n通常是微軟的文件會產生的,在其它的編輯器裡面,會在一行的節尾看到 ^M,那就是\r\n
在php中,字串中的\r\n或\n,要用雙引號才有效。
'\r'是回車,'\n'是換行,前者使光標到行首,後者使光標下移一格。通常用的Enter是兩個加起來。
參考資料:
http://blog.hsin.tw/2009/php-post-method-fsockopen/ php 傳送POST到別的URL並取得回應內容 使用fsockopen
http://stackoverflow.com/questions/2367458/php-post-data-with-fsockopen PHP Post data with Fsockopen
http://www.t086.com/code/php/function.php-fsockopen.php 函数:fsockopen()
http://seacatcry.pixnet.net/blog/post/13732061-%E3%80%90%E8%BD%89%E8%B2%BC%E3%80%91%5Cr%5Cn%E5%92%8C%5Cn%E7%9A%84%E5%B7%AE%E7%95%B0 【轉貼】\r\n和\n的差異
沒有留言:
張貼留言