fsockopen 異步非阻塞式請求數據

index.phpphp

<?php
ini_set ( "max_execution_time", "0" );
// 要傳遞的數據
$form_data = array (
    'name'   => 'testname',
    'gender' => 'man'
);

// 提交的文件信息
$file_data = array(
    array(
        'name'     => 'photo',
        'filename' => 'photo.jpg',
        'path'     => 'photo.jpg'
    )
);



// 請求地址端口信息
// 請求的域名例:baidu.com,這裏是 localhost
$host    = 'localhost';
$port    = 80;
$errno   = '';
$errstr  = '';
// 設置鏈接超時時間
$timeout = 60;
// 請求域名後詳細地址
$url     = '/test/index2.php?testget=testval';
//若是是GET    請求,可直接將編譯後的參數放到url上
//$url = $url . '?' . http_build_query ( $form_data );
//請求方式
$method  = "POST";


// 建立鏈接句柄
$fp = fsockopen ( $host, $port, $errno, $errstr, $timeout );
if (! $fp) {
    return false;
}

// 0,資源流將會被轉換爲非阻塞模式;若是是1,資源流將會被轉換爲阻塞模式
// 將此連接句柄變爲非阻塞模式,若是傳值中有文件,則異步無效,而且傳值數組中文件之後的傳值內容也沒法正常傳值
stream_set_blocking ( $fp, 0 );


//POST傳值有兩種方式
//===================== 第一種,無需傳遞文件 =====================
//格式化一下
$data = http_build_query ( $form_data );
// 也能夠傳遞json數據,直接json編譯下數組便可
// $data = json_encode ( $form_data ) ;
//===================== 第一種,無需傳遞文件結束 =====================

//===================== 第二種,能夠傳遞文件,但不能設置 stream_set_blocking 等於 0 =====================
/*
srand((double)microtime()*1000000);
$boundary = "---------------------------".substr(md5(rand(0,32000)),0,10);

$data = "--$boundary\r\n";
foreach($form_data as $key=>$val){
    $data .= "Content-Disposition: form-data; name=\"".$key."\"\r\n";
    $data .= "Content-type:text/plain\r\n\r\n";
    $data .= rawurlencode($val)."\r\n";
    $data .= "--$boundary\r\n";
}

// file data
foreach($file_data as $file){
    //獲取文件的類型信息
    $magicFile = get_cfg_var("magic_mime.magic");
    //要想使用 finfo 方法,需打開 php.ini 中 extension=php_fileinfo.dll 設置
    $finfo = new finfo(FILEINFO_MIME,$magicFile);
    //拼接提交文件的頭信息
    $data .= "Content-Disposition: form-data; name=\"".$file['name']."\"; filename=\"".$file['filename']."\"\r\n";
    $data .= "Content-Type: ". $finfo->file($file['path']) ."\r\n\r\n";
    $data .= implode("",file($file['path']))."\r\n";
    $data .= "--$boundary\r\n";
}

$data .="--\r\n\r\n";
*/
//===================== 第二種,能夠傳遞文件結束 =====================





// 鏈接句柄不報錯就拼接請求內容
$out = "${method} ${url} HTTP/1.1\r\n";
$out .= "Host:${host}\r\n";

//==============不一樣傳值方式 Content-type 值============================
//GET及POST第一種,無需傳遞文件
$out .= "Content-type:application/x-www-form-urlencoded\r\n";
//POST第二種,能夠傳遞文件
//$out .= "Content-type:multipart/form-data; boundary=$boundary\r\n";
//==============不一樣傳值方式 Content-type 值結束============================

$out .= "Content-length:" . strlen ( $data ) . "\r\n";
$out .= "Connection:close\r\n\r\n";
$out .= "${data}";

// 發送請求
fputs ( $fp, $out );

// 非阻塞模式須要設置系統延時,不然程序會不等待收到結果就往下執行代碼,這時會有獲取不到結果的狀況
// 具體設置延時多長時間,具體還要看接口的響應時間多久
usleep ( 5000 );

// 獲取返回內容(包含響應頭信息)
$response = '';

while ( $row = fread ( $fp, 4096 ) ) {
    $response .= $row;
}
//關閉連接
fclose ( $fp );

// 過濾返回的響應頭信息
// strpos() 函數查找字符串在另外一字符串中第一次出現的位置。
$pos    = strpos ( $response, "\r\n\r\n" );
$header = substr ( $response, 0, $pos );
$result = substr ( $response, $pos + 4 );

echo $header,"<br/>";
// 輸出返回結果
echo $result;

index2.phpjson

<?php
echo $_POST ['name'], "<br/>";
echo $_POST ['gender'], "<br/>";
echo $_GET ['testget'], "<br/>";

$filename = time () . '.jpg';
if (move_uploaded_file ( $_FILES ['photo'] ['tmp_name'], $filename )) {
    echo '<img src="' . $filename . '">';
}

/*
//post json方式傳值
$data = file_get_contents('php://input');
$data = json_decode($data,true);
echo $data['name'],"<br/>";
echo $data['gender'],"<br/>";
 */
exit ();
相關文章
相關標籤/搜索