fsockopen 异步非阻塞式请求数据

index.php

<?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.php

<?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 ();

 

posted @ 2018-11-26 13:56  风吹屁股凉冰冰  阅读(502)  评论(0编辑  收藏  举报